C++ global initialization order ignores dependencies?

Solution 1:

(1) the order of initialization of globals is not defined

Global variables in a single translation unit (source file) are initialized in the order in which they are defined.

The order of initialization of global variables in different translation units is unspecified.

(2) the order of initialization of globals ignores all dependencies

Right.

Is it possible to make sure the constructor of Foo is called before initializing dummy?

Yes, if globalFoo is defined before dummy and they are in the same translation unit.

One option would be to have a static pointer to the global instance; such a pointer will be initialized to null before any dynamic initialization takes place; addToGlobal can then test whether the pointer is null; if it is, then it is the first time the global is being used and addToGlobal can create the global Foo.

Solution 2:

On the order of initialization, read the answer here.

On how to solve the initialization issue, you can push the global to be a static local variable in a function. There standard guarantees that the static local variable will be initialized in the first call to the function:

class Foo {
public:
   static Foo& singleton() {
      static Foo instance;
      return instance;
   }
};

Then your other global variables would access the variable as:

Foo::singleton().add();

Note that this is not generally considered as a good design, and also that even if this solves the initialization issues, it does not solve the order of finalization, so you should be careful not to access the singleton after it has been destroyed.

Solution 3:

The most reliable way to provide correct init order for globals...

1) Init order depends on object files order passed to linker. Straight or reverse -not matter. You may create test application to detect it.

2) Use appropriate utilities( nm for example ) to discover imports & exports for each object file that contains globals.

3) Build the dependencies graph, sort object files and build required order for correct linking. Resolve cycles manually if exists.

I use such procedure in my makefiles on Linux. It works...