5

次の 2 つのソース ファイルに分割されたプログラムがあります。

たとえば .cpp

#include <iostream>

class A {
 public:
   A(int x) {
      ::std::cout << "In A(" << x << ")\n";
   }
};

static A first(1);
static A second(2);

__ main.cpp

int main(int argc, const char *argv[])
{
   return 0;
}

このプログラムの出力は次のようになることが保証されていますか?

In A(1)
In A(2)

すべてのプラットフォームとコンパイラで? もしそうなら、標準のどこにこれが書かれていますか?first名前空間を使用していて、別の名前空間に表示されていても問題はありsecondますか? それらが静的ではなく、匿名の名前空間を使用している場合はどうですか?

4

2 に答える 2

5

はい、宣言が同じ翻訳単位にある場合、非ローカル静的オブジェクトに対して初期化の順序が定義されます。

C++03 から、

(3.6/2) 同じ翻訳単位の名前空間スコープで定義され、動的に初期化される静的保存期間を持つオブジェクトは、それらの定義が翻訳単位に現れる順序で初期化されます。[注: 8.5.1 では、集約メンバーが初期化される順序について説明しています。ローカル静的オブジェクトの初期化については、6.7 で説明されています。]

于 2011-11-10T23:40:01.460 に答える
3

1つの変換ユニット内で、グローバル変数はいくつかの段階で初期化されます。

  • まず、「静的初期化」を持つすべての変数は、宣言の順序で初期化されます(以下を参照)。

  • 次に、すべての「順序付けられた動的初期化」が、再び宣言の順序で実行されます。

  • 「順序付けられていない動的初期化」もあります。これは、他の動的初期化に関して「順序付けられていません」(ただし、常に静的初期化の後に)。

静的および順序付けられた動的に初期化されたグローバルの破棄は、逆の順序で進行します(そして、順序付けされていないグローバルは再び「順序付けられていない」が、静的なものの前に)。TU間の相対的な初期化の順序は指定されていません。

用語を大まかに説明すると、グローバル変数は、定数に初期化される場合(コンストラクター呼び出しの場合、コンストラクターが必要constexpr)、または初期化子がなく宣言されstaticている場合(ゼロ初期化になります)、「静的に初期化」されます。 :static int a; Foo b(1, true, Blue);一方、初期化子が関数呼び出しや非constexprコンストラクターのように「定数」でない場合、オブジェクトは「動的に初期化」されます。動的に初期化されるほとんどの通常のグローバルは「順序付け」されています。「順序付けされていない」ものは、​​テンプレートの特殊化などの静的メンバーのみです。

(C ++ 11では、スレッドの開始時にスレッドローカルストレージと初期化に明確な注意が払われているため、これらすべてがより詳細になっていることに注意してください。)

于 2011-11-10T23:28:39.193 に答える