Reputation: 121
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?
Upvotes: 1
Views: 1697
Reputation: 145899
We have:
unsigned x = 1;
signed char y = -1;
this expression:
x > y
is used as the controlling expression of the if statement.
After usual arithmetic conversions the right operand y
will be converted to an unsigned int
value. The result of the conversion of the negative signed char
value -1
will be a huge unsigned int
value (equal to UINT_MAX
).
So the expression x > y
will be evaluated as:
1U > UINT_MAX
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:
Relational operators (C99, 6.5.8p3) "If both of the operands have arithmetic type, the usual arithmetic conversions are performed."
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?
Usual arithmetic conversions (C99, 6.3.1.8p1) "Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:`
Ok, first integer promotions is done on each operand. How are the integer promotions performed?
Integer promotions (C99, 6.3.1.1p2) "if an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions."
y
is of signed char
type so it is first promoted to int
after integer promotions and x
is of unsigned int
type and stays an unsigned int
.
Then usual arithmetic conversions will find a common type between both operands. In our case, it means this:
Usual arithmetic conversions (suite) (C99, 6.3.1.8p1) "Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type."
unsigned int
has the same conversion rank as the int
type (remember signed char
was promoted to int
), so the promoted y
will be converted from int
(after promotion) to unsigned int
. For information, integer conversion ranks are defined in (C99, 6.3.1.1p1).
As you can notice, unsigned int
wins over int
in usual arithmetic conversions, another way of saying this is to say that unsigned
is sticky.
Now how is an int
value of -1
(the signed char
-1
after its promotion to int
) converted to an unsigned int
value?`. Here is what C says on integer conversion in this specific case:
Integer conversions (C99, 6.3.1.3p2) "Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type."
This paragraph is written so its meaning remains independent of the signed number representation. For two's complement representation, it means the int
value -1
is converted to (UINT_MAX + 1) - 1
, which is equal to UINT_MAX
. So in our specific case,
x > y
is equivalent to
1U > UINT_MAX
is equivalent to
0
Upvotes: 10
Reputation: 339985
If you compare variables that aren't the same type, one of them has to be coerced into the type of the other before the comparison is done.
"Shorter" types will get promoted into "longer" types.
In this case signed char y
will have been converted into the unsigned int
with value UINT_MAX
.
Specifically, assuming a compiler that uses 32-bit ints
:
signed char -1 = 0xff becomes
-> signed int -1 = 0xffffffff becomes
-> unsigned int 0xffffffff = UINT_MAX
Hence x < y
.
Upvotes: 7
Reputation: 92371
Isn't 1 > -1?
It is, unless you use unsigned
values. In the world of unsigned
, the smallest values are zero and one. Everything else is larger, and the language explicitly states that unsigned(-1)
is the largest unsigned value.
Upvotes: 1