#include <stdio.h>
#include <stdint.h>
int main()
{
uint16_t peter = 8;
uint32_t peter2 = 8;
if(peter > -1)
{
printf("Peter true\n"); //expected
}
if (peter2 > -1)
{
printf("Peter 2 true\n"); //wtf, why not
}
return 0;
}
Why does the first statement enter the clause and the second does not (on a 32bit architecture)?
The explanation for the difference between peter > -1
and peter2 > -1
are the notions of “integer promotion”, and also “usual arithmetic conversions”.
“Integer promotion” means that any integer type t
narrower than int
is “promoted” to either int
(if int
can contain all the values of t
) or unsigned int
otherwise. In your example and with your compiler, promotion is applied to peter
, which is converted to int
before being compared to -1
(which also has type int
).
Then, the “usual arithmetic conversions” decide what happen when an arithmetic binary operation, here >
, is applied to operands of different types. Between an unsigned and a signed integer type of the same width, these rules say that the signed operand is converted to unsigned before the operation takes place.
-1
has type int
. When it is compared to peter2
, the usual arithmetic conversions mean -1
is converted to uint32_t
, becoming a large value (greater than 8
).