Signed and Unsigned Comparison in C
Many people would find it surprising to see the assertion fail, because -1 is obviously less than 2. However, the return type of sizeof
is size_t
,
which is an unsigned integer. On 64bit system, it’s probably unsigned long
. Then when int
is compared with unsigned long
, int
is converted to
unsigned long
.
1 | #include <stdlib.h> |
The partial usual arithmetic conversion rule is summarized here, see 6.3.1.8 in C11 for the complete specification.
- return if same type
- otherwise, if signness is the same, smaller integer is upcasted to larger one
- otherwise, if unsigned operand has larger or equal integer, signed integer is converted to unsigned
- otherwise, if sign type can represent all values of the unsigned type, unsigned integer is converted to signed, while preserving the value
- otherwise, both operands are converted to the unsigned version of the signed operand
In the code snippet, rule 3 is applied, for unsigned long
is larger, and -1
is super larger when interpreted as unsigned, hence the assertion
fails.
Now we understand this counterintuitive behavior, but having to struggle with it while programming in C is unbearable. Fortunately, turning on warning flags would expose this kind of madness.