2011-12-02 14 views
12

グローバル変数は、変換モジュールに表示される順番と、異なる変換モジュール内の変数の初期化の相対的な順序(不特定の「静的初期化順序の失敗」)で初期化されます。名前空間はC++の初期化順序に影響しますか?

名前空間に影響がありますか?

//second.cpp 
namespace { 
int first; 
} 
int second; 

は例があります名前空間にグローバルオブジェクトを置くことは、初期化順序に影響します。

//first.cpp 
int first; 
int second; 

が、それは、このコードに比べて初期化順序の違いがあります。たとえば、私はこのコードを持っている場合は?

+1

C++標準では、グローバルスコープ([basic.scope.namespace]/3)に表示されるものだけがグローバル名として定義されています。だからC++に関しては、second.cppの 'first'はグローバルではありません。明らかに、「グローバル」、とりわけ変化する「グローバル」がすべてのプログラミング言語で動作するPITAであることを実践するためには、それは「グローバル」です。 –

答えて

11

3.6静的記憶期間を持つ他の非局所変数は、順序付けられた初期化を持っています。単一の翻訳単位内に定義された順序付き初期化を伴う変数 は、翻訳単位内の定義の順に初期化されなければならない。

名前空間は、このセクションでは言及しません。

何が影響するのかは、異なる翻訳単位です。それらの間で順序を定義する必要がある場合は、GCCのconstructor属性などの拡張子を使用します。

+0

拡張を使用して順序を制御するのではなく、依存関係を完全に避けることをお勧めします。 –

+0

@DavidRodríguez-dribeasさらに静的なストレージを避けてください。 – Pubby

5

「グローバル変数は翻訳モジュールに表示される順に初期化されています」は明確です。名前空間のような他のもののために、注文に影響を及ぼす余地はありません。

実際には、「グローバル変数は順序通りに初期化されています...」という形式は、正式に間違っているため、標準の不正確な引用です。 C++標準からの正確な内容、ISO/IEC 14882:2003、3.6.2第1項は、次のとおりです。静的記憶域期間と同じ翻訳 単位で名前空間スコープで定義されていて、動的に初期化して

オブジェクトがで初期化されなければなりませんその定義が翻訳単位に表示される順序。

そうではなく、「静的記憶と」それは言う、「グローバル」、それは、彼らがグローバルな名前空間のメンバーやクラスメンバーと彼らはstaticか宣言されているかどうかであるかどうかをすべての非ローカル変数です。

また、「動的に初期化」されます。簡単なコンストラクタと定数初期化子を持つ変数は、(バイナリから値をロードするだけで)常に最初に初期化され、すべての非定数初期化子が評価され、非自明なコンストラクタがその順序で実行されます。これは重要です。たとえば、これらのコンストラクタでリンクリストを確実に作成することができます。頭が普通のポインタであれば、すでに初期化されているので、安全に作業できます。

+0

+1の強調表示: 'the"グローバル変数は、翻訳モジュールに表示される順番で初期化されます。物語の終わり! – Nawaz

+0

"definite"文は、グローバル変数にのみ該当します。ユーザー定義の名前空間のものはグローバルではありません –

+0

@ JohannesSchaub-litb:はい、グローバルです。あなたは仕様書の正確な言葉遣いを見せなければなりません。さて、ここに来る...(編集を参照してください)。 –

関連する問題