|
|
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;
}
line 6: warning: semantics of "<" change in ANSI 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. A two's-complement machine has:
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:Because this expression can be viewed as ambiguous (since differing compilers chose different meanings for the same code), the addition of a cast is as much to help the reader as it is to eliminate the warning message.(i + (int)uc) < 17
unsigned preserving:
(i + (unsigned int)uc) < 17