In his "Thinking in C++" (Chapter 10) Eckel describes a technique that was pioneered by Jerry Schwarz to solve the fiasco. He says that if we want to initialize x to 100 and y to 200 and share them among all translation units, we create an Initializer.h that looks like this:
extern int x;
extern int y;
class Initializer {
static int initCount;
// if (initCount++ == 0) x = 100 & y = 200
/* ... */
};
static Initializer init;
And in implementation file we have
#include "Initializer.h"
int x;
int y;
int Initializer::initCount;
and Eckel says that "static initialization (in implementation file) will force all these values to zero".
Let me consider the following case: the compiler processes the implementation file after some other file with that header included (it means that x and y have been already set to 100 and 200 in that other file). The compiler sees int x, so what will it do? Will it set x and y to zero eliminating initialization and all possible changes in previous files? But if it does, then initCount will also be set to zero, breaking down the whole technique.
I'm not sure what you mean by this. If
xandyare defined in other files, then you have a linker clash and the program simply won't compile.If
x,yand most importantlyInitializer::initCountare implemented in this way, there will be unique instances of them in the program; they are effectively global and will be initialized to0at program start, before anyInitializeris constructed (due to inclusion of the header declaring astaticinstance of that class). Each construction of astatic Initializerwill first check whether any otherInitializers have been constructed due to theif (initCount++ == 0)etc.The first
Initializerctor to run (still before enteringmain) will thus set all three values.