I'm using Visual Studio 2013, which doesn't have "magic statics" feature implemented yet, so local static variables initialization isn't yet thread-safe. So, instead of
Foo& GetInstance()
{
static Foo foo;
return foo;
}
I do something like this:
std::unique_ptr<Foo> gp_foo;
std::once_flag g_flag;
Foo& GetInstance()
{
std::call_once(g_flag, [](){ gp_foo = std::make_unique<Foo>(); });
return *gp_foo;
}
But I don't like the idea of having gp_foo
and g_flag
global variables (first, problem with the order of initialization of static variables in different translation units; second, I would like to initialize variables only when we need them, i.e. after first call to GetInstance()), so I implemented the following:
Foo& GetInstance()
{
// I replaced a smart pointer
// with a raw one just to be more "safe"
// not sure such replacing is really needed
static Foo *p_foo = nullptr;
static std::once_flag flag;
std::call_once(flag, [](){ p_foo = new Foo; });
return *p_foo;
}
And it seems to work (at least it passes the tests), but I'm not sure it's thread-safe, because here we have the same potential problem with the initialization of static local variables p_foo
and flag
in multiple threads. Initialization of raw pointer with nullptr
and initialization of std::once_flag
seems more innocent than calling Foo
's constructor, but I would like to know whether it is really safe.
So, are there any problems with the last code snippet?