In the following code, assume that an unsigned char is smaller than an int.
int f(void) { int i = -2; unsigned char uc = 1; return (i + uc) < 17; } |
The code above causes the compiler to issue the following warning when you use the -xtransition option:
line 6: warning: semantics of "<" change in ISO C; use explicit cast
The result of the addition has type int (value preserving) or unsigned int (unsigned preserving), but the bit pattern does not change between these two. On a two’s-complement machine, we have:
i: 111...110 (-2) + uc: 000...001 ( 1) =================== 111...111 (-1 or UINT_MAX) |
This bit representation corresponds to -1 for int and UINT_MAX for unsigned int. Thus, if the result has type int, a signed comparison is used and the less-than test is true; if the result has type unsigned int, an unsigned comparison is used and the less-than test is false.
The addition of a cast serves to specify which of the two behaviors is desired:
value preserving: (i + (int)uc) < 17 unsigned preserving: (i + (unsigned int)uc) < 17 |
Since differing compilers chose different meanings for the same code, this expression can be ambiguous. The addition of a cast is as much to help the reader as it is to eliminate the warning message.