implicit conversions!

why the result is wrong ?

1
2
3
4
5
6
7
8
unsigned int uival = 88;
signed int ival = 55;
unsigned short usval = 44;
signed short sval = 55;
signed long lval = 15;
cout << typeid(usval + sval).name() << endl; // result : signed int 
cout << typeid(uival + lval).name() << endl; // result : unsigned long 
cout << typeid(ival + usval).name() << endl; // result : signed int 


in the first case :
unsigned short "usval" should be promoted to unsigned int and signed short "sval" should be promoted to signed int then signed int will be converted to unsigned int then the result should be unsigned int but the compiler result is signed int ? why

in the second case :
the signedness is different and the unsigned int has lesser conversion rank than signed long but all values in unsigned int doesn't fit in signed long (in my machine) so the signed long will be converted to the unsigned int then the result should be unsigned int but the compiler result is unsigned long ????

int the third case :
unsigned short "usval" should be promoted to unsigned int and the signedness is different but the unsigned int has the same rank as signed int so signed int will be converted to unsigned int then the result should be unsigned int but the compiler result is signed int ??

Arithmetic Conversions (cppreference) :

If the types after promotion are the same, that type is the common type
Otherwise, if both operands after promotion have the same signedness (both signed or both unsigned), the operand with the lesser conversion rank (see below) is implicitly converted to the type of the operand with the greater conversion rank
Otherwise, the signedness is different: If the operand with the unsigned type has conversion rank greater or equal than the rank of the type of the signed operand, then the operand with the signed type is implicitly converted to the unsigned type
Otherwise, the signedness is different and the signed operand's rank is greater than unsigned operand's rank. In this case, if the signed type can represent all values of the unsigned type, then the operand with the unsigned type is implicitly converted to the type of the signed operand.
Otherwise, both operands undergo implicit conversion to the unsigned type counterpart of the signed operand's type.


conversion rank (as mentioned in cppreference) :

1 ) rank of signed char < rank of short < rank of int < rank of long int < rank of long long int
2 ) the ranks of all signed integer types equal the ranks of the corresponding unsigned integer types


so what is the problem in my result ?
Last edited on
First case:

Both usval and sval are promoted to int.

http://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_promotion
The following implicit conversions are classified as integral promotions:
• signed char or signed short can be converted to int;
• unsigned char or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise;
• ...



Second case:

According to your own quote both types will be converted to unsigned long.

Otherwise, both operands undergo implicit conversion to the unsigned type counterpart of the signed operand's type.

The signed operand's type is long, and the unsigned type counterpart of long is unsigned long.


Third case:

Again, usval is promoted to int.
Last edited on
thanks Peter87. it's clear now :)

i just translated the text wrong so i didn't understand right

but in this rule :
[qoute]
• unsigned char or unsigned short can be converted to int if it can hold its entire value range, and unsigned int otherwise;
[/qoute]

the range of int is from -2147483648 to 2147483647
and unsigned char is from 0 to 255 and unsigned short is from 0 to 65,535

so it can hold the entire values of unsigned short and unsigned char
how may they be promoted to unsigned int ?
Last edited on
The ranges of the integer types are implementation defined, so it is possible for int to have the same range as short. This is mainly the case on 16 bit systems.

With modern compilers for 32 and 64 bit systems an int is usually 32 bits while a short is 16 bits which means the range of int is more than enough to store the entire range of unsigned short.

http://en.cppreference.com/w/cpp/language/types#Integer_types
Last edited on
Thanks you so much ,Peter87.
i understood now :)
Topic archived. No new replies allowed.