How to trick C/C++ compilers into generating terrible code?
futurechips.org
futurechips.org
In the dead code example, the gcc function attribute 'const' can be applied to the declaration of bar(), telling the compiler that it is a pure function whose result depends on nothing but its arguments.
In the pointer example, the C99 standard 'restrict' qualifier can be applied to a, b and c to tell the compiler that the values pointed to by these variables do not overlap.
'restrict' will also help the global variable example - the reason that N is loaded each time around the loop is because as far as the compiler knows, one of the a[i]s could alias with N.
Also, gcc does not seem to warn about reading eternal memory. It seems like this would be an easy error for the compiler to detect.
A pure function is still allowed to allocate memory, though, and throw an exception.
The "meaning" of const is that the function depends on nothing but its arguments, and can therefore have its value computed at compile time, or be part of a global CSE pass. That's a different optimization.
One other way would be to target different hardware than it's designed to work with via flags, or by using AMD with the intel compiler mentioned in the article. There was a very short discussion about this on reddit yesterday http://www.reddit.com/r/programming/comments/lj1ze/ask_rprog...
Some of the DSP tool suites have solid compilers that optimize insightfully for their target architecture but whose in-circuit debuggers are tied to flaky IDEs. I'm currently working with an XDP debugger on a Sandy Bridge board that requires the debugger software to be restarted nearly hourly, often corrupting the project file requiring me to enter the memory map again.
Lately I've been thrilled to spec in ARM micros because I can just use GCC, an el-cheapo universal USB JTAG adapter through OpenOCD, and expect everything to work.
The OP didn't mention what compiler was being used; GCC will certainly automatically vectorize this example (and ICC probably will as well). I used GCC 4.4 for x86 with -O3 -msse2.
Of course, there's a lot of compensation code inserted for unaligned pointers and aliased pointers and the like, but automatic vectorization is certainly doable.
But, there's still no free lunch. For example, as of about two months ago, ICC will unroll loops whose increment is "i++" but will not unroll loops whose increment is "i+=1". Some insight, looking at output assembly, etc. is still required.
This is because global variables can be modified at runtime unless they're const. The compiler cannot guarantee it hasn't been declared extern and modified by some other file without sufficiently powerful link-time optimization.