Doing whatever with undefined behavior is fine. But GCC must do everything it can to warn the programmer when it encounters undefined behavior.
My impression is that GCC is doing a poor job of that; as noted in the article, it doesn't give a warning with -O2. GCC should exist to help the programmer, not to follow the spec at any cost, and ignore the programmer's needs. If GCC can't give proper warnings, then they should turn off the optimizations, IMO.
Posted Mar 23, 2013 15:22 UTC (Sat) by ssam (subscriber, #46587)
[Link]
its not so much that the compiler has gone, 'ah huh, this function is undefined so i can replace it with whatever i like'. more that its gone, 'You used dd=d[++k], so if you are assuming that k will always be less that 16, then i can assume that too, hence i'll replace "k<16" with "true".' once it has made that step, it can see that the loop will never finish, and so the function will never return, so why bother calculating anything.
Posted Mar 23, 2013 16:16 UTC (Sat) by HelloWorld (guest, #56129)
[Link]
That is an academic distinction. The point is that gcc should give a warning when one uses a very unusual syntax like k < 16 to express 1, because chances are that wasn't the original intent.
Posted Mar 23, 2013 16:38 UTC (Sat) by ssam (subscriber, #46587)
[Link]
a 'expression always evaluates to true' or 'expression always evaluates to true' warning. It might be a pain for bits of code that you want the compiler to remove.
I sometimes use code like:
int a[] = {6,8,3};
...
for (int i=0; i<(sizeof(a)/sizeof(int)); i++){
done_stuff_with(a[i]);
}
...
maybe because i want to check if a particle in a simulation is in one of my regions of interest. I may often modify a, and then recompile the code (in my work its not unusual to recompile code before each run). Sometimes a will just be {}, so i would like the compiler remove the loop.
Posted Mar 23, 2013 17:32 UTC (Sat) by apoelstra (subscriber, #75205)
[Link]
> maybe because i want to check if a particle in a simulation is in one of my regions of interest. I may often modify a, and then recompile the code (in my work its not unusual to recompile code before each run). Sometimes a will just be {}, so i would like the compiler remove the loop.
I do this too, and I also compile with -Werror, but IMHO I'd rather have the warning than not. A simple (ugly) solution is to couch your loop in #ifdef's, and just flip a preprocessor variable.
Posted Mar 26, 2013 5:31 UTC (Tue) by bronson (subscriber, #4806)
[Link]
I think ifdefs would fall apart too quickly to be of much use.
Compiler warnings would too... If the compiler emits 22 "might be true" warnings, and 21 of them are spurious, what are the chances I'll catch the meaningful one? Knowing me, probably next to nil.
Posted Mar 23, 2013 18:24 UTC (Sat) by smurf (subscriber, #17840)
[Link]
>> The point is that gcc should give a warning when one uses a very
>> unusual syntax like k < 16 to express 1, because chances are that
>> wasn't the original intent.
The problem is that this kind of thing comes up in macros all the time, esp. in hand-optimized libraries. "(Foo < 8) ? _handcoded_special_function() : _generic_function()" is a common-enough idiom. You cannot just warn about that.
Posted Mar 23, 2013 18:52 UTC (Sat) by mansr (guest, #85328)
[Link]
A common strategy is to not warn for integer constant expressions used in conditions while warning if a condition involving a non-constant expression is provably invariant.
In some loops that have known constant number of iterations, but undefined behavior is known to occur in the loop before reaching or during the last iteration, GCC will warn about the undefined behavior in the loop instead of deriving lower upper bound of the number of iterations for the loop. The warning can be disabled with -Wno-aggressive-loop-optimizations.
Posted Mar 23, 2013 15:31 UTC (Sat) by proski (subscriber, #104)
[Link]
It's actually a common programming mistake often found by Valgrind. I'm afraid the new gcc would generate the code that would behave in unexpected ways without triggering Valgrind warnings.
Posted Mar 25, 2013 13:41 UTC (Mon) by dlthomas (guest, #89935)
[Link]
It's not constraining the lookup, which would make valgrind miss it, but constraining its later assumptions about the variable.
int d[16];
d[k] = 10; /*A*/
if(/*B*/ k < 16) {
...
}
The idea is that when it hits A, if that expression would be false, behavior is already undefined because of what happened at B, so let's optimize for the case that didn't segfault (or corrupt data).