I am a bit confused by the static in-class initialization of a const member. For example, in the code below:
#include <iostream> struct Foo { const static int n = 42; }; // const int Foo::n; // No ODR void f(const int& param) { std::cout << param << std::endl; } int g(const int& param) { return param; } template<int N> void h() { std::cout << N << std::endl; } int main() { // f(Foo::n); // linker error, both g++/clang++ std::cout << g(Foo::n) << std::endl; // OK in g++ only with -O(1,2 or 3) flag, why?! h<Foo::n>(); // this should be fine } I do not define Foo::n (the line is commented). So, I expect the call f(Foo::n) to fail at link time, and indeed it does. However, the following line std::cout << g(Foo::n) << std::endl; compiles and links fine only by gcc (clang still emits a linker error) whenever I use an optimization flag such as -O1/2/3.
- Why does gcc (tried with gcc5.2.0 and gcc 4.9.3) compile and link the code when the optimization is turned on?
- And am I correct to say that the only usage of in-class static const members is in constant expressions, such as template parameters like in the
h<Foo::n>call, in which case the code should link?
-std=c++11, but the question per se is not necessarily C++11 (or C++14) only. O observed the same behaviour with-std=c++98also.