Within the same compilation unit, the C++ standard says that static initialization order is well defined -- it's the order of the declarations of the static objects.
In your shown code you have no declaration of a static data member. You have a declaration of a typedef-name. These have nothing to do with that, and don't influence any order. You probably think along this way:
If i make that typedef declaration, it will instantiate helper<int>
, and thus instantiate its static data member declaration first.
The problem is, that line does not cause an instantiation of helper<int>
. For that to happen, you would need an explicit instantiation or manage to make it instantiate it implicitly (creating an object of helper<int>
for example, or using it as a nested name specifier as in helper<int>::...
and explicitly referencing the static member - otherwise, creation of it is omitted).
But there is a much deeper problem. The order is not the declaration of the static data-members. The order is their definition. Consider the following
struct C { C() { printf("hey\n"); } };
struct A {
static C a;
static C b;
};
C A::b;
C A::a;
In this code, b is created before a, even though a is declared before b.
The following code prints 2 1
:
struct C { C(int n) { printf("%d\n", n); } };
template<int N>
struct A {
static C c;
};
template<int N>
C A<N>::c(N);
// explicit instantiation of declaration and definition
template struct A<2>;
template struct A<1>;
int main() {
}
But the following code prints nothing, unless you comment in the line in main
.
struct C { C(int n) { printf("%d\n", n); } };
template<int N>
struct A {
static C c;
};
template<int N>
C A<N>::c(N);
// implicit instantiation of declarations
A<2> a2;
A<1> a1;
int main() {
// A<1>::c; A<2>::c;
}
I'm not actually sure what the correct output for this second snippet is. Reading the Standard, i can't determine an order. It says at 14.6.4.1
"Point of Instantiation":
For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization [...]. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.
The point of instantiation of their definitions both appear immediately after the definition of main
. Which definition is instantiated before the other definition seems to be left unspecified. If anyone knows the answer and khow other compilers behave (GCC prints 1 2
but with the order of the expressions in main
swapped, prints 2 1
), please let me know in the comment.
For details, see this answer about static object's lifetime.