barcaroller said:
Does anyone know why the gcc compiler complains about the
second 'if' condition:
unsigned char x = 0;
size_t y = 0;
// okay; no compiler warning
if (x < y)
...
// compiler warning: comparing signed and unsigned values
if ((x+1) < y)
...
My guess is that (x+1) somehow becomes an 'int',
As does x in the first case.
Well, actually, it depends on the implementation. If INT_MAX
can hold the range 0..UCHAR_MAX, then x will be promoted to
a (signed) int, otherwise it will be promoted to an unsigned
int for comparison purposes. It may be subject to further
'arithmetic' conversion depending on size_t.
I dare say that gcc is checking if the two operands are
unsigned (prior to integral promotion.) If so, then the
comparison is fine. If not, then the comparison may or
may not be fine, hence the warning.
but that would not be intuitive and could have undesirable
consequences.
Intuitive or not, it is what the C language requires.
However, you can rest assured that any promotion is value
preserving for non-negative values. That said, x + 1, is
theoretically problematic and you should check your code
for errant behaviour on bizarre implementations, should
you wish the code to be maximally portable.
If you want the mathematical condition to hold, then the
second clause can be written portably as...
if (y != 0 && x < y - 1)
The original code can fail in the case where y is non-zero
and x has the value UCHAR_MAX, and x promotes to unsigned
int. In that case x + 1 will yield 0 (as an unsigned int)
which of course compares less than a positive value, even
if y has a positive value lower UCHAR_MAX.