web-dev-qa-db-ja.com

Cの静的変数の初期化

Cの静的変数の初期化について質問があります。デフォルトで値が0であるグローバルな静的変数を宣言するかどうかはわかります。例えば:

static int a; //although we do not initialize it, the value of a is 0

しかし、次のデータ構造についてはどうですか:

typedef struct
{
    int a;
    int b;
    int c;
} Hello;

static Hello hello[3];

hello[0]hello[1]hello[2]の各構造体のすべてのメンバーは、0として初期化されていますか?

36
user707549

はい、すべてのメンバーは静的ストレージを持つオブジェクトに対して初期化されます。 C99標準(PDFドキュメント) の6.7.8/10を参照してください

自動保存期間を持つオブジェクトが明示的に初期化されていない場合、その値は不定です。 静的な保存期間を持つオブジェクトが明示的に初期化されていない場合、次のようになります:
—ポインタータイプの場合、nullポインターに初期化されます。
—算術型の場合、ゼロ(正または符号なし)に初期化されます。
—集約の場合、すべてのメンバーはこれらの規則に従って(再帰的に)初期化されます。
—ユニオンの場合、最初の名前付きメンバーはこれらの規則に従って(再帰的に)初期化されます。

オブジェクト内のすべてを、staticであるかどうかにかかわらず、0に初期化するには、universal zero initializerを使用します

sometype identifier0 = {0};
someothertype identifier1[SOMESIZE] = {0};
anytype identifier2[SIZE1][SIZE2][SIZE3] = {0};

Cには部分的な初期化はありません。オブジェクトは完全に初期化されます(0別の値がない場合に適切な種類の)またはまったく初期化されていません。
部分的な初期化が必要な場合、最初から初期化することはできません。

int a[2]; // uninitialized
int b[2] = {42}; // b[0] == 42; b[1] == 0;
a[0] = -1; // reading a[1] invokes UB
50
pmg

はい、静的またはスレッドの保存期間がある限りです。

C11(n1570)、§6.7.9初期化#1

静的またはスレッドの保存期間を持つオブジェクトが明示的に初期化されていない場合、次のようになります。

[...]

  • 算術型の場合、(正または符号なし)ゼロに初期化されます。
  • 集約の場合、すべてのメンバーはこれらの規則に従って(再帰的に)初期化され、パディングはゼロビットに初期化されます。

[...]

2
md5

はい、ファイルスコープの静的変数は、構造体、配列などのすべてのメンバーを含め、ゼロに初期化されます。

参考として この質問 を参照してください(これも重複としてクローズすることに投票します)。


編集:この質問ははるかに良い回答を得ているので、代わりにthisの複製としてthat質問を閉じることを投票しています。

参照用に、ここに C FAQ link その質問の受け入れられた回答からのものですが、もちろんここにリンクされているC99およびC11標準は標準です。

2
Useless

静的変数(または配列)は2つのタイプに分類されます。

Initializedは、コンパイル時にコードから値が与えられるものです。これらは通常DSに格納されますが、これはコンパイラ固有のものです。

もう1つのタイプはuninitializedstaticsで、実行時に初期化され、BSSセグメントに格納されますが、これもコンパイラ固有です。

[〜#〜] bss [〜#〜]

1
fayyazkl