yohhoyの日記

技術的メモをしていきたい日記

static変数初期化とスレッドセーフ

yamasaさんのDCL解説記事で知った、「C++11規格においてブロックスコープなstatic変数の初期化処理はマルチスレッドセーフ」に関するメモ。

該当箇所をN3337 6.7/p4より一部引用。(下線部は強調)

Otherwise 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 the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.88 If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
脚注88) The implementation must not introduce any deadlock around execution of the initializer.

gcc

gcc 4.0.0から既定動作でスレッドセーフなコードが出力される。(自動的に排他制御コードが埋め込まれる。)

  • The compiler now uses the library interface specified by the C++ ABI for thread-safe initialization of function-scope static variables. Most users should leave this alone, but embedded programmers may want to disable this by specifying -fno-threadsafe-statics for a small savings in code size.
http://gcc.gnu.org/gcc-4.0/changes.html

Visual C++

2015-05-01追記:Visual Studio 2015 RCにてThread-safe "magic" staticsをサポート。

出力されるx86アセンブラコードを見る限り、Visual Studio 2010(MSVC10)、Visual Studio 11(MSVC11) Betaともに非対応。また、2012年3月時点のMSDNでは下記の通り残念な記述が…

Note
Assigning a value to a static local variable in a multithreaded application is not thread safe and we do not recommend it as a programming practice.

http://msdn.microsoft.com/en-us/library/s1sb61xd%28v=vs.110%29.aspx

2012-04-12追記:GCCClangではN2660通り"Dynamic initialization and destruction with concurrency"だが、MSVCでは"Magic statics"と呼称している?


関連URL