27

According to following resources, in C++(Specially Visual C++) scoped static variable initialization isn't thread safe. But, global static variables are safe.

Thread-safe static variables without mutexing?

http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx

So, is following code with static member variable thread-safe?

class TestClass
{
public:
   static MyClass m_instance;
}

Myclass TestClass::m_instance;

Thanks in advance!

Community
  • 1
  • 1
Varuna
  • 1,198
  • 1
  • 18
  • 19
  • 1
    Seems true even 5 years after: http://blogs.msdn.com/b/vcblog/archive/2013/12/02/c-11-14-core-language-features-in-vs-2013-and-the-nov-2013-ctp.aspx (see "Magic statics") :) – mlvljr Nov 21 '14 at 03:14
  • 1
    Apparently, [VS 2015 finally fixes this](http://stackoverflow.com/a/28098631/1505939) – M.M Dec 29 '15 at 04:48

2 Answers2

40

It's more a question of function-scoped static variables vs. every other kind of static variable, rather than scoped vs. globals.

All non-function-scope static variables are constructed before main(), while there is only one active thread. Function-scope static variables are constructed the first time their containing function is called. The standard is silent on the question of how function-level statics are constructed when the function is called on multiple threads. However, every implementation I've worked with uses a lock around the constructor (with a twice-checked flag) to guarantee thread-safety.

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
  • 4
    The standard is also silent on how non-function-scoped statics are constructed with multiple threads. IIRC all that is guaranteed is that the object is initialized before any other code in the translation unit is executed (that is, code not called by initializers). If you consider the code might be in a dll loaded after main() begins executing, you see that this is the best that realistically can be guaranteed. It's the particular threading specification that makes any further guarantees, not the C++ standard. – Steve Jessop Dec 26 '09 at 11:46
  • g++ (as in GCC) guarantees thread safe initialization of both global and function static variables and plants the required code to block other threads during initialization. – Martin York Dec 26 '09 at 17:02
  • 7
    gcc uses locks to make function level statics threadsafe (can be disabled by a flag). Most (all?) versions of Visual C++ do NOT have threadsafe function level statics. – tony Dec 27 '09 at 05:06
  • In C++11 [std::call_once](https://en.cppreference.com/w/cpp/thread/call_once) can be used to ensure that initialization only happens once across threads. – Andre Holzner Sep 11 '19 at 04:22
4

Yes(*). When global statics are initialized, there is only one thread around and all constructors are called on it. This is not true for function's statics, though.

(*) One can possibly make global statics not thread-safe by creating threads in some of the constructors and scheduling some initialization stages on these threads. In this case usual thread safety rules apply.

Rom
  • 4,129
  • 23
  • 18
  • 1
    I may create threads in constructors if it's the last program I am writing ;-) – Varuna Dec 26 '09 at 14:27
  • 3
    @Varuna: sometimes you don't have a choice or you don't even know that threads are created in your constructors. This usually happens when objects which are being constructed are using third-party libraries. – Rom Jan 27 '10 at 20:03