223
votes

I know this is an often asked question, but as there are so many variants, I'd like to re-state it, and hopefully have an answer reflecting the current state. Something like

Logger& g_logger() {
    static Logger lg;
    return lg;
}

Is the constructor of variable lg guaranteed to run only once?

I know from previous answers that in C++03, this is not; in C++0x draft, this is enforced. But I'd like a clearer answer to

  1. In C++11 standard (not draft), is the thread-safe initialization behavior finalized?
  2. If the above is yes, in current latest releases of popular compilers, namely gcc 4.7, vc 2011 and clang 3.0, are they properly implemented?
2
@Chris: Deterministic initialization and avoidance of the static initialization order fiasco. Local statics will first be initialized when the function is called the first time. - Xeo
Thanks Xeo, that's the main reason. Some others include: 1. Normally in a logging system, client code use it as macro, like LOG << "your log" ..., and the macros have to have an deterministic access to the logger 2. The logger is not created if you don't use it. 3. You probably don't want your client to create multiple loggers (there are synchronization issue, etc...) so the Logger has a private constructor, which is only accessible by friend g_logger() - Ralph Zhang
@balki, GCC has implemented it for nearly a decade. Clang supports it too. - Jonathan Wakely
Nor, does it appear, will Visual Studio 2013. See the row "Magic statics" at msdn.microsoft.com/en-us/library/vstudio/… - rkjnsn
"Magic statics" are finally coming with VS 2015: blogs.msdn.com/b/vcblog/archive/2014/11/17/… - mlvljr

2 Answers

202
votes

The relevant section 6.7:

such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. [...] If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.

Then there's a footnote:

The implementation must not introduce any deadlock around execution of the initializer.

So yes, you're safe.

(This says nothing of course about the subsequent access to the variable through the reference.)

22
votes

--fno-threadsafe-statics also worth mentioning. In gcc:

Do not emit the extra code to use the routines specified in the C++ ABI for thread-safe initialization of local statics. You can use this option to reduce code size slightly in code that doesn't need to be thread-safe.

Also, have a look at the old thread Are function static variables thread-safe in GCC?