Can I get a static initialization order fiasco failure when I access static members through a static function?

StackOverflow https://stackoverflow.com/questions/6084222

Question

Is this particular code prone to the static initialization order fiasco? I.e. can I assume that static initialization in compilation unit "B" is already done when I access B's static member function?

// a.h
struct A {
    static int foo();
    static int var;
}

// a.cpp
#include <a.h>
int A::foo() {
    return var;
}
int A::var = 42;


// b.h
struct B {
    B::B();
    static int var;
}

// b.cpp
#include <b.h>
#include <a.h>
B::B() {
    var = A::foo();
}

// c.h
struct C {
    static B b;
}

// c.cpp
B C::b;

Or do I have the code like that:

// a.h
static int &A::var();

// a.cpp
int &A::var() {
    static value = 42;
    return value;
}

int A::foo() {
    return var();
}

References to the standard would be appreciated.

Was it helpful?

Solution

Yes you can see the problem when accessing through a static function.
See example below guaranteed to fail.

The way to solve this is not to access "Static storage duration objects" before main has started.

If for some reason you need to access objects from the constructor of a "Static Storage duration object" then these objects should be wrapped up so that you gurantee that they are fully constructed before use. The best way to do this is to use "static function objects" (a type of static storage duration object that are constructed on demand).

// a.cpp
MyType&  A::getInstance()
{
    static MyType myInstance;
    return myInstance;
}

Example guaranteed to fail:

struct A
{
     static A  instanceA1;
     static A& getInstance() { return instanceA1;}
};

struct B
{
     static B instanceB1;
     static B& getInstance() { return instnaceB1;}
     A& member;

     B(): member(A::getInstance()) {}
}

B B::instanceB1;   // Constructure uses A::getInstance() which returns A::instance
                   // But A::instance has not been constructed yet.
                   // Order of instanciation in the same compilation unit is guranteed
                   // So we know this will not work.
A A::instanceA1;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top