The problem regarding static initialization is known as static initialization order fiasco:
In short, suppose you have two static objects x and y which exist in
separate source files, say x.cpp and y.cpp. Suppose further that the
initialization for the y object (typically the y object’s constructor)
calls some method on the x object.
So if you have another translation unit using your constants, you have a rather good chance that your program will not work. Sometimes it is the order the files were linked together, some plattforms even define it in the doc (I think Solaris is one example here).
The problem also applies to builtin types such as int. The example from the FAQ is:
#include <iostream>
int f(); // forward declaration
int g(); // forward declaration
int x = f();
int y = g();
int f()
{
std::cout << "using 'y' (which is " << y << ")\n";
return 3*y + 7;
}
int g()
{
std::cout << "initializing 'y'\n";
return 5;
}
int main() {
std::cout << x << std::endl << y << std::endl;
return 0;
}
If you run this example, the output is:
using 'y' (which is 0)
initializing 'y'
So y first gets zero-initialized and then constant initialization (?) happens.
The solution is the Construct On First Use Idiom:
The basic idea of the Construct On First Use Idiom is to wrap your
static object inside a function.
Static loca objects are constructed the first time the control flow reaches their declaration.