Minimal example and question
In this example, an inline static member variable c2 of a nontemplate class is initialized when the class member is instantiated, and member variable c1 of a template class is not. What is the difference? Why is c1 not being initialized unless I force it to be by taking its address, and c2 is initialized unconditionally?
struct C1 {
C1() { std::cerr << "C1()\n"; }
};
struct C2 {
C2() { std::cerr << "C2()\n"; }
};
template<typename T>
struct Template {
inline static C1 c1;
};
struct Nontemplate {
inline static C2 c2;
};
int main() {
Template<int> a;
Nontemplate b;
(void)a;
(void)b;
}
// Output:
C2()
Context and reasoning
Here's a bit of context to the minimal example. I have the Nontemplate class inherited from Template<something>, and the constructor of c2 depends on c1. I expect c1 to be created before c2; however, that is not the case.
template<typename T>
struct Template {
inline static C1 c1;
};
struct Nontemplate : public Template<int> {
struct C2 {
C2() {
std::cerr << "Do something with Nontemplate::C1\n";
std::cerr << "&Nontemplate::c1 = " << &Nontemplate::c1 << "\n";
}
};
inline static C2 c2;
};
int main() {
Nontemplate b;
(void)b;
}
// Output:
Do something with Nontemplate::C1
&Nontemplate::c1 = 0x600ea8
C1()
The code was compiled with g++ 7.2 with -std=c++17 flags. Both -O0 and -O2 give the same result.