Sure, but then you deserve what you get...
Posted May 25, 2011 3:31 UTC (Wed) by iabervon
In reply to: Sure, but then you deserve what you get...
Parent article: What Every C Programmer Should Know About Undefined Behavior #3/3
Actually, if the compiler is forced to consider overflow, it just has to think a little harder before making the same optimizations. The compiler can determine that 1<<32 / GCD(1<<32, 0x04040404) > 256/4 and thus that the first time i >= 256/4, val == 0x04030200 with unsigned math, and val != 0x04030200 before that. Your loop would have to get slower (or, more likely, take an additional register) if it was going to use the same value in "val" multiple times, simply because it becomes necessary to track another piece of information.
(Also note that it doesn't matter if you declare the loop counter as an "unsigned int"; the nominal loop counter actually gets discarded entirely, in favor of a proxy loop counter, which is what could overflow.)
With gcc 4.4.5, replacing "int val" with "unsigned int val" makes it actually generate what you would expect of:
for (val = 0x03020100; val != 0x04030200; val += 0x04040404, value++)
*value = val;
which avoids the "i = 0", "*value = val" is a simpler instruction than "value[i] = val", and uses one fewer register; but it still actually works. If the constant you're adding is 0x04000000, the optimization doesn't work, and gcc produces the slower code. The code it produces for "unsigned int" is the fastest working code possible, so it's not getting slower in any meaningful way by using "unsigned int" (I mean, it loops faster without testing the end condition, but...).
to post comments)