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.
But if it is true, and the compiler handles the implementation file after some another file, than it will set x and y to zero eliminating initialization and all possible changes in previous files?
I'm not sure what you mean by this. If x
and y
are defined in other files, then you have a linker clash and the program simply won't compile.
If x
, y
and most importantly Initializer::initCount
are implemented in this way, there will be unique instances of them in the program; they are effectively global and will be initialized to 0
at program start, before any Initializer
is constructed (due to inclusion of the header declaring a static
instance of that class). Each construction of a static Initializer
will first check whether any other Initializer
s have been constructed due to the if (initCount++ == 0)
etc.
The first Initializer
ctor to run (still before entering main
) will thus set all three values.