I'm having difficulty understanding why the following code doesn't warn:
unsigned test = 0xffffffff;
for (unsigned char i = 0; i < test; i++)
{
// Some code
}
This is on Visual Studio 2010, but GCC apparently doesn't warn either. Anyone know why?
From a language point of view, there is nothing to warn about. i
is promoted to unsigned int
before the <
is evaluated. And it's perfectly well-defined to increment an unsigned char
such that it wraps around to zero.
The fact that this code does something irritating is unfortunate. But it's not clear what rule a compiler would need to apply in order to detect this sort of thing.
Thanks to @unwind in the comments below: you can get GCC to warn about the fact that this comparison must always evaluate to true using the -Wtype-limits
flag.
Update 2: Apparently the above option doesn't work in this case (I don't have a "modern" version of GCC to hand right now...)
From the draft standard:
4.5 Integral promotions
A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.
i
is promoted to unsigned
and then compared to test
. No problems here. Well. i++ will overflow the char, but that is a run-time problem. What I mean is that after 255 it will be 0, and that maybe not what the author espect, making the cycle potencialy infinite if there are not other form of terminating it ( a break, a retun, etc) That is a posible "logical" run time error.
Because comparing an unsigned char
and unsigned
is perfectly legal. The problem only starts to show up due to the loop counter obviously overflowing, but I'm not sure compilers will ever be that smart.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With