== Your C compiler's optimizer can make your bad programs compile Every so often I learn something by having something brought to my awareness. Today's version is that one surprising side effect of optimization in C compilers can be to make your program compile. The story starts with [[John Regehr http://blog.regehr.org/]]'s tweets: > [[@johnregehr https://twitter.com/johnregehr/status/753091105298714625]]: > tonight I am annoyed by: a program that both gcc and clang compile > at -O2 and neither compiles at -O0 \\ > > [[@johnregehr https://twitter.com/johnregehr/status/753092002208702465]]: > easier to arrange than you might think \\ > > void bar(void); \\ > static int x; \\ > int main(void) { if (x) bar(); } (With the Fedora 23 versions of gcc 5.3.1 and clang 3.7.0, this will fail to compile at -O0 but compile at -O1 or higher.) I had to think about this for a bit before the penny dropped and I realized where the problem was and why it happens this way. John Regehr means that this is the whole program (there are no other files), so _bar()_ is undefined. However, _x_ is always 0; it's initialized to 0 by the rules of C, it's not visible outside this file since it's _static_, and there's nothing here that creates a path to change it. With optimization, the compiler can thus turn _main()_ into: .pn prewrap on > int main(void) { if (0) bar(); } This makes the call to _bar()_ unreachable, so the compiler removes it. This leaves the program with no references to _bar()_, so it can be linked even though _bar()_ is not defined anywhere. Without optimization, an attempt to call _bar()_ remains in the compiled code (even though it will never be reached in execution) and then linking fails with an error about 'undefined reference to `bar''. (The optimized code that both gcc and clang generate boil down to '_int main(void) { return 0; }_', as you'd expect. You can explore the actual code through the very handy [[GCC/clang compiler explorer https://gcc.godbolt.org/]].) As reported on Twitter by Jed Davis, [[this can apparently happen accidentally in real code https://twitter.com/xlerb/status/753250715938586624]] (in this case Firefox, with a C++ variant).