6

次のコードでセグメンテーション違反(またはUB)が発生すると予想していました。

struct T {
   T();
};

T t;
char const* str = "Test string";

T::T() {
   std::cout << str; // zero-initialised, only!
}

int main() {}

これは、がのt前に初期化されるためですstr。初期化がゼロであるためstr、値を保持することを期待します。(char const*)0私の解釈は[C++11: 3.6.2/2]これをサポートしています。

ただし、上記のスニペットは期待どおりに文字列を出力しているように見えます(そして、ポインターの値も出力することで動作を確認しました)。

ここで欠落している静的初期化のルールがありますか?これにより、構築を開始strする前に値を初期化できますか?t標準のどこにありますか?


これは、ビルド時の静的変数の解決でchar const*発生しました。回答者は、静的グローバルではなくを使用するとstd::string、静的初期化順序の失敗を回避できると主張しました。同意しませんでしたが、今はよくわかりません...

4

4 に答える 4

6

str定数式によって初期化され、const char *POD 型です (C++03 の用語ですが、C++11 は類似していますが、用語が異なり、より多くのケースが許可されています)。このような初期化は静的初期化フェーズで行われ、静的初期化フェーズには順序の問題はありません。動的初期化の前に発生します。動的初期化フェーズで初期化されます。t

于 2012-01-05T22:00:48.723 に答える
1

通常の意味では、組み込み型はまったく初期化されません。通常、それらの初期コンテンツは、バイナリのロードの一部として、バイナリの特別な領域から直接メモリ マップされます。

于 2012-01-05T22:00:09.513 に答える
1

見つけたと思います。ここで起こっていることは、組み込み型ではなく、定数初期化子に関するものです。

[C++11: 3.6.2/2]:静的保存期間 (3.7.1) またはスレッド保存期間 (3.7.2) を持つ変数は、他の初期化が行われる前にゼロで初期化されます (8.5)。

一定の初期化が実行されます。

  • 静的またはスレッド保存期間を持つ参照の初期化子に現れる各完全式(暗黙的な変換を含む) が定数式 (5.19) であり、参照が静的保存期間を持つオブジェクトを指定する左辺値または一時的な(12.2 を参照);
  • 静的またはスレッドのストレージ期間を持つオブジェクトがコンストラクター呼び出しによって初期化される場合、コンストラクターがconstexprコンストラクターである場合、すべてのコンストラクター引数が定数式 (変換を含む) である場合、および関数呼び出し置換 (7.1.5) の後、すべてのコンストラクターが非静的データ メンバーのmem-initializersおよび波括弧または等号初期化子の call および full-expression は定数式です。
  • 静的またはスレッド ストレージ期間を持つオブジェクトがコンストラクター呼び出しによって初期化されず、その初期化子に現れるすべての完全式が定数式である場合。

ゼロ初期化と定数初期化をまとめて静的初期化と呼びます。他のすべての初期化は動的初期化です。静的初期化は、動的初期化が行われる前に実行されます。[..]

その最後の文は、後続の順序付けルールをオーバーライドするように見え、この順序付けが翻訳単位全体に適用されます。

于 2012-01-05T22:01:48.677 に答える
0
char const* str = "Test string";

コンパイラ/リンカーによって行われるため、プログラムが実行を開始する前に「初期化された状態」で存在します。

于 2012-01-05T22:01:42.373 に答える