ProgrammingC++ System Architect / Senior Software Engineer

What is the order of initialization of global and static objects in C++? How can one guarantee correct initialization between different translation units?

Pass interviews with Hintsage AI assistant

Answer.

In C++, global and static objects are initialized before entering the main() function. However, the standard does not guarantee the order of initialization of objects located in different translation units (compilation files). This can lead to the so-called "static initialization order fiasco" — a bug where one global object refers to another that has not yet been initialized.

To guarantee correct initialization and avoid the problem, the "construct on first use" pattern is used: a function is declared that returns a reference to a static local object (it is created on first call in a thread-safe way with C++11).

Code example (construct on first use pattern):

// foo.h class Config { public: int value; }; Config& getConfig() { static Config config; config.value = 42; // initialization guaranteed! return config; }

Trick question.

If two different .cpp files create global objects that reference each other, what will happen?

Answer: The result is undefined; there may be a reference to an uninitialized object. The solution is to replace direct global initialization with lazy initialization via a static local object inside the function (see above).


Story

-In a CRM system, two modules declared global loggers that referenced each other during initialization. In different builds of the application, the order of initialization changed, leading to elusive bugs: crashes and logging to a null pointer.


Story

-In a graphical engine, a global resource container object referenced a global resource manager. On Linux and Windows, compilers implemented the loading order differently, resulting in desynchronization and various crashes.


Story

-A developer introduced global initialization of settings, and later a colleague added another global variable that depended on those settings. It worked locally but broke on CI, where a different arrangement of modules occurred.