web-dev-qa-db-ja.com

グローバル変数と静的変数がデフォルト値に初期化されるのはなぜですか?

C/C++では、なぜグローバル変数と静的変数がデフォルト値に初期化されるのですか?

ゴミ値だけを残してみませんか?これには特別な理由がありますか?

60
Xinus
  1. Security:メモリをそのままにしておくと、他のプロセスまたはカーネルから情報がリークします。

  2. Efficiency:値は何かに初期化されるまで役に立たず、展開されたループのあるブロックで値をゼロにする方が効率的です。 OSは、一部のクライアントまたはユーザーがプログラムの開始を待機しているときではなく、システムがアイドル状態のときにフリーリストページをゼロにすることさえできます。

  3. Reproducibility:値をそのままにしておくと、プログラムの動作が再現できなくなり、バグを見つけるのが非常に難しくなります。

  4. Elegance:デフォルトのイニシャライザでコードを乱雑にすることなくプログラムを0から開始できれば、よりクリーンです。

すると、なぜautoストレージクラスdoesがゴミとして始まるのか疑問に思うかもしれません。答えは2つあります。

  1. ないある意味。各レベルの最初のスタックフレームページ(つまり、スタックに追加されるすべての新しいページ)は、ゼロの値を受け取ります。同じスタックレベルの後続の関数インスタンスに表示される「ガベージ」または「初期化されていない」値は、実際には、独自のプログラムおよびそのライブラリの他のメソッドインスタンスによって残された以前の値です。

  2. 二次的(または何でも)実行時のパフォーマンスペナルティ何かにauto(関数ローカル)を初期化することに関連する可能性があります。関数は、たとえば特定の呼び出しで大きな配列の一部またはすべてを使用しない場合があり、数千または数百万回呼び出される可能性があります。静的およびグローバルの初期化であるOTOHは、一度だけ実行する必要があります。

68
DigitalRoss

OSの適切な協力により、実行時のオーバーヘッドなしで、静的およびグローバルを初期化する0を実装できるためです。

24

セクション6.7.8 C99標準(n1256)の初期化は、この質問に答えます。

自動保存期間を持つオブジェクトが明示的に初期化されていない場合、その値は不定です。静的ストレージ期間を持つオブジェクトが明示的に初期化されていない場合、次のようになります。

—ポインタータイプがある場合、nullポインターに初期化されます。

—算術型の場合、(正または符号なし)ゼロに初期化されます。

—集約の場合、すべてのメンバーはこれらの規則に従って(再帰的に)初期化されます。

—ユニオンの場合、最初の名前付きメンバーはこれらの規則に従って(再帰的に)初期化されます。

17
Jingguo Yao

考えてみてください。静的な領域では、何かが実際に初期化されているか、メインが起動したかを常に確認できるとは限りません。また、静的initフェーズと動的initフェーズがあります。静的フェーズは、順序が重要な動的フェーズの直後です。

静的なものをゼロにすることがなかった場合、このフェーズで何かが初期化されたかどうかを完全に知ることはできませんAT ALLそして要するにC++の世界はばらばらになり、基本的なことシングルトン(またはあらゆる種類の動的な静的初期化)のように、単純に機能しなくなります。

箇条書きの答えは熱狂的ですが、少しばかげています。これらはすべて非静的割り当てに適用できますが、それは行われません(まあ、通常ではありませんが)。

6

Cでは、明示的な初期化子のない静的に割り当てられたオブジェクトは、ゼロ(算術型の場合)またはnullポインター(ポインター型の場合)に初期化されます。 Cの実装は通常、ゼロ値のビットのみで構成されるビットパターンを使用して、ゼロ値とヌルポインター値を表します(ただし、これはC標準では必要ありません)。 したがって、bssセクションには通常、ファイルスコープ(つまり、関数の外部)で宣言されたすべての初期化されていない変数と、staticキーワードで宣言された初期化されていないローカル変数が含まれます。

ソース: Wikipedia

3