For demonstration purposes, suppose 8-bit char and 32-bit int s.
unsigned char k=-1;
k assigned the value 255.
if(k==-1)
The left side of the == operator is equal to unsigned char . The right side is int . Since all possible unsigned char values ββcan fit inside an int , the left side is converted to an int (this is done due to the whole promotions given below). This leads to a comparison (255 == -1) , which is incorrect.
unsigned int k=-1
k assigned the value 4294967295
if(k==-1)
This time, the left side (unsigned int) cannot be placed in int. The standard says that in this case both values ββare converted to unsigned int. Thus, this leads to a comparison (4294967295 == 4294967295) , which is true.
Relevant quotes from the standard:
Integer shares: (C99, 6.3.1.1p2)
If int can represent all values ββof the original type, the value is converted to int; otherwise, it will be converted to unsigned int.
Common arithmetic conversions: (6.3.1.8).
[For whole operands] whole actions are performed on both operands. Then, for advanced operands, the following rules apply:
- If both operands are of the same type, then further conversion is not required.
...
- Otherwise, if the operand with an unsigned integer type has a rank greater than or equal to the ranks of the type of another operand, then the operand with an integer type with a sign is converted to the type of an unsigned operand of an integer type ....
source share