Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is overloading on all of the fundamental integer types is sufficient to capture all integers?

Let's say I have function overloads for all standard integer types:

void foo( char );
void foo( signed char );
void foo( short );
void foo( int );
void foo( long );
void foo( long long );
// .... all unsigned variants as well

Is it possible that those overloads would fail to find proper overload for types like int8_t or something like that? Is there a portable way to handle such overloads?

How about references?

To clarify the question: it comes from discussion of this question Why is int8_t read as a character? and claims that there could be compiler generated integer types that would be not an alias to fundamental C++ types. So in such case overloads for all fundamental case may not accept it. On another way I cannot provide overload for int8_t as on many platforms it is just an alias and will get error for redefinition of existing overload.

like image 766
Slava Avatar asked Jan 09 '17 16:01

Slava


1 Answers

The standard does not provide a guarantee that the standard integer types are the only integer types supported by the compiler. Indeed, the C and C++ standards explicitly give permission to compilers to define other integer types, collectively known as "extended integer types":

There may also be implementation-defined extended signed integer types.

Likewise, for each of the extended signed integer types there exists a corresponding extended unsigned integer type ...

the extended signed integer types and extended unsigned integer types are collectively called the extended integer types.

And the C standard does not prohibit an implementation from using extended integer types to implement the stdint.h types. There is even this non-normative notation, just to make it clear:

Some of these types may denote implementation-defined extended integer types.

If you want a function that can take any integer type, you have two options: make it a template (probably using SFINAE to disallow non-integral types) or provide a single overload that takes std::intmax_t. The standard requires that intmax_t is the largest integer supported:

designates a signed integer type capable of representing any value of any signed integer type

And of course "signed integer type" includes standard and extended types. So std::intmax_t can handle any signed integer that the implementation supports.

like image 69
Nicol Bolas Avatar answered Nov 15 '22 02:11

Nicol Bolas