I know the following is a thread-safe way to implement a singleton in C++11:
Foo* getInst()
{
static Foo* inst = new Foo(...);
return inst;
}
Static variables are NOT allocated on the stack. In the first variant you have a static pointer (a global variable) initialized with a memory obtained from the heap, while in the second one you have whole static object.
Both versions use internal compiler guards (namely __cxa_guard_acquire()
and __cxa_guard_release()
, which are functionally equivalent to mutex::lock()
and mutex::unlock()
) to ensure serialized access to a special variable that tells whether or not your global instances are already initialized or not.
Your code:
Foo& getInst()
{
static Foo inst(...);
return inst;
}
will actually look like that after the compilation:
Foo& getInst()
{
static Foo inst; // uninitialized - zero
static guard instGuard; // zero
if (is_initialized(instGuard) == false)
{
__cxa_guard_acquire(instGuard);
// do the initialization here - calls Foo constructor
set_initialized(instGuard);
__cxa_guard_release(instGuard);
}
return inst;
}
So both of your exampes are thread safe.
inst
in your example won't be allocated on stack. It will be allocated somewhere in .data
or .bss
section. Otherwise this static variable couldn't live all the time program executes, and so it couldn't have the same value, which was before, each time you enter this function.