1. ホーム
  2. c++

[解決済み】C++11でローカル静的変数の初期化はスレッドセーフか?重複

2022-04-07 10:26:06

質問

よくある質問だと思いますが、あまりにバリエーションが多いので、改めて記載し、現状を反映した回答ができればと思います。例えば

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

変数 lg のコンストラクタは一度だけ実行されることが保証されていますか?

以前の回答で、C++03ではそうでなく、C++0xドラフトでは、これが強制されることを知っています。しかし、次のような明確な答えが欲しいです。

  1. C++11標準(ドラフトではない)では、スレッドセーフな初期化動作は確定しているのでしょうか?
  2. 上記が「はい」の場合、一般的なコンパイラの現在の最新リリース、すなわちgcc 4.7、vc 2011、clang 3.0では、これらは適切に実装されていますか?

解決方法は?

該当する6.7項をご覧ください。

このような変数は、制御がその宣言を最初に通過したときに初期化され、初期化が完了した時点で初期化されたとみなされます。[変数が初期化されている間に制御が宣言に同時に入る場合、同時実行は初期化の完了を待つものとする。

次に脚注です。

実装は、イニシャライザの実行に伴うデッドロックを発生させてはならない。

そう、安全なんですね。

(もちろん、これはその後の参照による変数へのアクセスについては何も言っていません)。