> Lots of real C++ code is order-sensitive. This is a serious problem and > there are a couple of ugly solutions to it.
I'd say that the best solution would be to get rid of globals. This is actually very easy: If you have TYPE VAR = INITIALIZER; replace that with TYPE& getVAR(){ static TYPE obj = INITIALIZER; return obj; } Then use getVAR() whereever you've used VAR before. For backwards compatibility, you can even do #define VAR (getVAR()) In understand that modules don't share global objects (perhaps except for the module singleton), so removing global should be a local change inside each module only. > To get the calling order right. CLN consists of >800 source-code > modules and uses a bridge pattern to abstract the actual > implementation away from the interface. In cln-1.1.2.orig, there are 864 .cc files inside src, but only 43 of them use CL_PROVIDE. So I think changing those modules is a much smaller change than you may anticipate. > The best solution would be to teach the linker about it. The linker actually does know about constructor order. In g++, there is a guarantee that object files within the same executable or shared library are initialized from right to left, in the order in which the objects appear on the linker line. > The solution we are talking about here is just a rather > unconventional but beautiful one. Looking at the code in module.h, I'd question that there is anything beautiful about it. > Rather than that or changing the module ordering macros and writing > autoconf scripts to see if the global dtors are making use of > cxa-atexit I guess I'll just switch on -fno-use-cxa-atexit in CLN > whenever GCC-3.x is used. Hope this'll work for a couple of > years... I very much doubt that. Somebody will notice that the _GLOBAL__ symbols don't need unique names at all, since they are not global (in fact, static_initialization_and_destruction is already in gcc 2.95 a single function for both ctors and dtors, so it is questionable whether these "clever" macros really get the control flow right). Furthermore, the C++ ABI really specifies that the .init and .fini sections shouldn't be used for constructors and destructors. For constructors, .initarray should be used, to allow portable integration of constructors across different compilers. Destructor sections should not be used, instead, cxa_atexit won't be an option at some time in the future. Regards, Martin