https://isocpp.org/wiki/faq/ctors
What’s the “static initialization order fiasco”?
A subtle way to crash your program.
The static initialization order fiasco is a very subtle and commonly misunderstood aspect of C++. Unfortunately it’s very hard to detect — the errors often occur before main() begins.
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 xobject.
That’s it. It’s that simple.
The tragedy is that you have a 50%-50% chance of dying. If the compilation unit for x.cpp happens to get initialized first, all is well. But if the compilation unit for y.cpp get initialized first, then y’s initialization will get run before x’s initialization, and you’re toast. E.g., y’s constructor could call a method on the x object, yet the x object hasn’t yet been constructed.
I hear they’re hiring down at McDonalds. Enjoy your new job flipping burgers.
If you think it’s “exciting” to play Russian Roulette with live rounds in half the chambers, you can stop reading here. On the other hand if you like to improve your chances of survival by preventing disasters in a systematic way, you probably want to read the next FAQ.
Note: The static initialization order fiasco can also, in some cases, apply to built-in/intrinsic types.
Some attributes only make sense for C++ programs.
init_priority (priority)
In Standard C++, objects defined at namespace scope are guaranteed to be initialized in an order in strict accordance with that of their definitions in a given translation unit. No guarantee is made for initializations across translation units. However, GNU C++ allows users to control the order of initialization of objects defined at namespace scope with the init_priority attribute by specifying a relative priority, a constant integral expression currently bounded between 101 and 65535 inclusive. Lower numbers indicate a higher priority.
In the following example, A would normally be created before B, but the init_priority attribute has reversed that order:
Some_Class A __attribute__ ((init_priority (2000)));
Some_Class B __attribute__ ((init_priority (543)));
Note that the particular values of priority do not matter; only their relative ordering.