c++c++03static-order-fiasco

Calling a function of another translation unit can cause static initialization order fiasco


a.cpp

static Foo fooobj;
void Usefoo()
{
    foooobj.somefunc();
}

b.cpp

static Bar barobj;

and here is the constructor of Bar

 Bar::Bar()
 {
     Usefoo();
 }

Will this lead to static initialization order fiasco? If yes, how can I solve it. I thought of something like below:

Foo* GetFoo*()
{
    static Foo *fooobj = new Foo();
    return fooobj;
}

But since I don't have support of C++11, static local initialization is not thread safe. Hence this cannot work.

Also what if barobj was non-static. Then I don't have to worry about this fiasco right? For a non-static object initialization which is depending on another non-static object initialization in a different translation unit is not an issue. Right?


Solution

  • Will this lead to static initialization order fiasco?

    Yes.

    I thought of something like below:

    Usually you'd avoid the pointers and do a nice:

    Foo& GetFoo()
    {
        static Foo fooobj;
        return fooobj;
    }
    

    But since I don't have support of C++11, static local initialization is not thread safe.

    Okay, still problematic then.

    Also what if barobj was non-static. Then I don't have to worry about this fiasco right?

    Right. You should avoid these globals. In fact, this is a pretty good example of why we try to avoid globals.

    Encapsulate your state into a nice class, perhaps instantiated in main and passed around as needed, instead.

    For a non-static object initialization which is depending on another non-static object initialization in a different translation unit is not an issue. Right?

    Right. I can't think of a way to break that unless your program has undefined behaviour.