The C++ standard leaves the relative initialization order of global and static data undefined. The only thing that the compilers must guarantee is that all such data have been initialized before the invocation of main(). In any large and well-designed project, there are no or very few global objects. But static member data in classes are unavoidable in many occasions.
The unspecified and unguaranteed relative order of initialization of these objects can lead to undesirable effects. You could very well end up using objects that have not been initialized yet.
This is my problem. I’m in the design stage of a large library, and I want to know any thoughts or useful material you might have or have seen relevant to this problem. (This library is a game engine, by the way, and we will be delighted to have anyone with enthusiasm and technical expertise on board with us.)
One solution that comes to mind is doing all the initialization of static object in functions (for example, one per each class with static data members) and “registering” these functions and their relative priority at the static initialization time (before main()) but do not invoke them then. The only static object that is actually initialized pre-main is the object that we register these initialization functions to. At the beginning of main(), the said registrar object goes through its list of init functions, sorted by relative priority, and invokes them one by one. The static objects can register termination functions as well to be invoked at the termination of main. This way, the relative order is ensured and the initialization and termination are done pre-main (actually, only before all the objects initialized in main(), but after the start of main() itself,) and post-main, respectively.
The problems with this scheme are the verbosity of writing initialization/termination functions, and the fact that the static objects are constructed before main() anyway. We only re-initialize them. This can be costly, wrong or plain impossible, depending on the design of each specific class.
Has anyone got a better way? Any illumination?
Printer-friendly version
mojtaba | 29-Nov-07 at 2:15 am | Permalink
static initialization order fiasco:
I would suggest this:
http://libcw.sourceforge.net/global/global.html
and if thread safety is important, this:
http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx