# 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.