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?