2

It's my understanding that char may have a different underlying type depending on the architecture.
During implicit casting, an unsigned char may become and int or an unsigned int.

enter image description here

Does that mean the following code has unspecified behaviour?

#include <iostream>

void function(unsigned int){
    std::cout << "unsigned\n";
}
void function(int){
    std::cout << "signed\n";
}

int main() {
    char c;
    function(c);
}

I don't get any compiler warnings. Will it always resolve to "signed"?

Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271
  • As long as `sizeof int > sizeof char`, yes. – Revolver_Ocelot Jun 24 '16 at 13:11
  • More accurately, as long as an `int` can represent every value that an `unsigned char` can. A consequence of that, practically, is that `sizeof int > sizeof char (= 1)`. – Peter Jun 24 '16 at 13:26
  • Possible duplicate of [Do I need to cast to unsigned char before calling toupper?](http://stackoverflow.com/questions/21805674/do-i-need-to-cast-to-unsigned-char-before-calling-toupper) – Jonathan Mee Jun 24 '16 at 13:28

3 Answers3

3

Your diagram is correct for the case of integer promotion. However, in the code function(c), integer promotion does not happen. This is actually overload resolution. If there were only one function then c is converted (not promoted) to the type of the parameter, whichever it is.

In the rules for overload resolution, if the argument could be made to match the parameter by integer promotion, then that function would be considered a better match than another function where integer conversion is required to match.

See Table 12 in C++14 (part of section 13.3.3.1.2) which lists the ranks of implicit conversion sequences for overload resolution.

So your code sample would call function(unsigned int) on a system with CHAR_MAX > INT_MAX.

However the sizes of types are implementation-defined, not unspecified.

M.M
  • 138,810
  • 21
  • 208
  • 365
1

A char will almost always be converted to an int. Whenever the sizeof(int) > sizeof(char) then a char will be promoted to an int regardless if it is signed or unsigned as like you said int can hold the entire range of char.

The only time you could get an unsigned int is when sizeof(char) == sizeof(int). In this case if char is unsigned then it would be converted to an unsigned int since int would not be able to hold the entire range of values.

This can happen as the standard only dictates that an int must have at least as much storage as a char so there could be some system that has 32 bit bytes and they make char and int the same size.

So this is implementation defined behavior as you need to know the implementation defined size of both types and the implementation defined signedness of char to know what will happen.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
-1

This is just one kind of C++ feature, called "Implicit type conversion/automatic type conversion/coercion". when you pass a char to the function, the char was converted to signed int implicitly. Just like the code "int a = 'C';" You can learn more about coercion from here: http://www.learncpp.com/cpp-tutorial/44-implicit-type-conversion-coercion/

Under the hood, all types are represented as binary number, So the type is just one way of explanation of the compile. There's no such mechanism you state above

wenqi
  • 21
  • 4