In C++ worden globale en statische objecten geïnitialiseerd voordat de main()-functie wordt binnengetreden. Echter, de standaard garandeert niet de volgorde van initialisatie van objecten, die zich in verschillende vertaalunits (compilatiebestanden, translation units) bevinden. Dit kan leiden tot de zogenaamde 'static initialization order fiasco' — een bug waarbij een globaal object naar een ander verwijst, dat nog niet is geïnitialiseerd.
Om een correcte initialisatie te garanderen en het probleem te vermijden, wordt het patroon "construct on first use" gebruikt: een functie wordt gedeclareerd die een verwijzing naar een statisch lokaal object retourneert (dit wordt bij de eerste aanroep veilig gegenereerd met C++11).
// foo.h class Config { public: int value; }; Config& getConfig() { static Config config; config.value = 42; // initialisatie gegarandeerd! return config; }
Als in twee verschillende .cpp-bestanden globale objecten elkaar creëren, wat gebeurt er dan?
Antwoord: Het resultaat is onbepaald, er kan een verwijzing naar een niet-geïnitialiseerd object plaatsvinden. Oplossing — vervang directe globale initialisatie door luie initialisatie via een statisch lokaal object binnen de functie (zie hierboven).
Verhaal
-In een CRM-systeem hadden twee modules globale loggers gedeclareerd die bij initialisatie naar elkaar verwezen. In verschillende builds van de applicatie veranderde de volgorde van initialisatie, wat leidde tot moeilijk te traceren bugs: crashes en logging naar een nulverwijzing.
Verhaal
-In een grafische engine verwees een globaal object-containertje voor bronnen naar de resource manager, die zelf globaal was. Op Linux en Windows implementeerden de compilers de volgorde van laden op verschillende manieren, wat leidde tot desynchronisatie en verschillende crashes.
Verhaal
-Een ontwikkelaar introduceerde globale initialisatie van instellingen, en later voegde een collega een andere globale variabele toe die afhankelijk was van deze instellingen. Dit werkte lokaal maar faalde op CI, waar een andere samenstelling van modules gebeurde.