Any interested GCC maintainers/contributors: I have a suggestion for GCC to eliminate a pernicious problem - that of automatically initialising static (i.e. long-lived) variables in the correct order based on mutual dependencies, apparently not normally addressed by compilers. This is a thorny issue, and is normally discovered the hard way by most programmers - not the way to produce robust code. I would welcome any correspondence/queries on the matter.
The suggestion is for a simple modification to GCC to ensure that static variables are always initialised (and destroyed) in the correct order determined by dependencies between the actual variables concerned - this applies to both C and C++. Someone may already have tackled this issue, though I don't see it on the GNU site. I would be happy to supply example code to illustrate the concept to any interested person. I have a very simple approach to (a) ensure that every static variable used in initialising another is always initialised beforehand, even when this dependency is hidden from the compiler, and (b) detect (unfortunately not at compile time) when correct initialisation is impossible due to a cyclic dependency. A more involved mechanism can also (c) ensure that no static variable is destroyed before its last use. The essence of the idea for (a) is: - Access each static variable including static class members via (inlined) wrapper code in the same way as is typical for function-local variables (i.e. initialised once on first access using a flag). This ensures that every static variable gets initialised before use, especially where such use is in the initialisation of another static variable. - Retain initialisation of static variables before calling main() (via the wrapper code). This ensures that initialisation always occurs before main() is called as would be expected, and does so in a single-threaded environment, eliminating any need for a mutex. - Preferably initialise all function-local variables at this point too - initialisation in a multi-threaded environment using a simple flag (as opposed to a mutex) is non-reentrant, and can fail sporadically. This modification would have the effect that function-local statics will always be initialised before calling main() even if never used. The alternative is to use a mutex, which may be problematic (OS-dependent). - I would avoid the approach apparently taken in C# and Java - that of initialising all statics in each class as a set (this is not as robust, since references between classes may be cyclic without cyclic dependencies for initialisation. Note that this means that statics in a class may be initialised after the first instances of the class are constructed, unless used by the constructor. The approach taken for (b) is to have an intermediate state for the flag indicating that the initialisation of a given variable is in progress but not yet complete. If the initialisation is triggered a second time in this state, a cyclic dependency exists. The approach for (c) involves triggering initialisation of every object with a destructor early enough that the "atexit" call to the destructor occurs after that of every object that has methods that accesses it. This can be dealt with separately, and I will omit the detail for now. Note that these changes are probably largely ANSI-compliant, and as such may not have to be treated as an extension. When applied to global ("extern") variables, additional linker information is needed (a reference to the flag and initialisation code). This will introduce problems when linking code generated by different versions of the compiler. Manfred von Willich