Deferring C++ static object construction - GCC on Linux

Since you've constrained the problem such that new cannot be used, you should be able to create the object as always and copy it to the global instance. For example:

MyClass createMyClass()
{
    doGlobalSetup();
    return MyClass(1, 2, 3);
}

MyClass myInstance = createMyClass();

int main()
{
    myInstance.doSomething();

    return 0;
}

Does it suit your needs?

namespace
{
    int doStaticGlobalSetup()
    {
        doGlobalSetup();
        return 0;
    }
}
MyClass myInstance(doStaticGlobalSetup() + 1,2,3);

int main() {
   myInstance.doSomething();
   return 0;
}

If you absolutely have to defer any constructor calls until after global initialization is done, and want to be sure that no static order initialization fiasco happens, there is a way: make myInstance a reference to uninitialized block of memory and create object in it using placement new after global initializaton.

#include <iostream>
#include <type_traits>

struct foo
{
    foo() { std::cout << "created\n"; }
    void meow() { std::cout << "used\n"; }
    ~foo() { std::cout << "destroyed\n"; }
};
void doGlobalSetup() { std::cout << "Global setup\n"; }


//Actual implementation
namespace {
    typename std::aligned_storage<sizeof(foo), alignof(foo)>::type bar;
}
foo& instance = reinterpret_cast<foo&>(bar);

//Allows automatic creation and destruction
struct initializer
{
    initializer()
    {
        if (!initialized)
            new (&instance) foo();
        initialized = true;
    }
    ~initializer()
    {
        if(initialized)
            instance.~foo();
        initialized = false;
    }
    private:
        static bool initialized;
};
bool initializer::initialized = false;

int main()
{
    doGlobalSetup();
    initializer _;
    instance.meow();
}

Tags:

C++

Gcc