The reason for this has to do with the method in which the signed value is converted to unsigned.
Section 6.3.1.3 of the C standard regarding conversions of signed and unsigned integers dictates how this occurs:
2 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.60)
...
60) The rules describe arithmetic on the mathematical value, not the value of a given type of expression.
In your example with b
equal to -20, when it is converted to unsigned UINT_MAX + 1
is added to the value, so the converted value is UINT_MAX - 19
. When you then add the value of a
(6), you get UINT_MAX - 13
. This value is larger than a
, so "> a"
is printed.
If you set b
equal to -5, the converted value is UINT_MAX - 4
. Adding 6 to this gives you UINT_MAX + 2
. Since math on unsigned int
values occurs modulo UINT_MAX + 1
, the actual result is 1. This is less than 6, so "< a"
is printed.
Also, what is happening here is not integer promotion but integer conversion. Promotion happens first if any integer type in an expression has a rank less than int
. That is not the case here.