I wrote this small piece of code to test something:
#include <stdio.h>
int main()
{
unsigned x = 1;
signed char y = -1 ;
if (x>y)
printf("X > Y");
else
printf("X <= Y");
return 0;
}
The output I got was “X <= Y”. Isn’t 1 > -1?
We have:
this expression:
is used as the controlling expression of the if statement.
After usual arithmetic conversions the right operand
ywill be converted to anunsigned intvalue. The result of the conversion of the negativesigned charvalue-1will be a hugeunsigned intvalue (equal toUINT_MAX).So the expression
x > ywill be evaluated as:which is always false (i.e., evaluated to 0).
This is the short version. To explain how do we come to this result with the C standard rules, I explain it below.
Here is how it goes:
The
>relational operator is used, here it was C says on the relational operators:Ok, in our example both operand are of integer types and integer types are of arithmetic types. So usual arithmetic conversion will be done. What are the usual arithmetic conversions?
Ok, first integer promotions is done on each operand. How are the integer promotions performed?
yis ofsigned chartype so it is first promoted tointafter integer promotions andxis ofunsigned inttype and stays anunsigned int.Then usual arithmetic conversions will find a common type between both operands. In our case, it means this:
unsigned inthas the same conversion rank as theinttype (remembersigned charwas promoted toint), so the promotedywill be converted fromint(after promotion) tounsigned int. For information, integer conversion ranks are defined in (C99, 6.3.1.1p1).As you can notice,
unsigned intwins overintin usual arithmetic conversions, another way of saying this is to say thatunsignedis sticky.Now how is an
intvalue of-1(thesigned char-1after its promotion toint) converted to anunsigned intvalue?`. Here is what C says on integer conversion in this specific case:This paragraph is written so its meaning remains independent of the signed number representation. For two’s complement representation, it means the
intvalue-1is converted to(UINT_MAX + 1) - 1, which is equal toUINT_MAX. So in our specific case,is equivalent to
is equivalent to