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.
A pure function is still allowed to allocate memory, though, and throw an exception.
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.
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...
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.