array [100] = {0}は配列全体を0にどのように設定しますか?


140

コンパイラはどのように値を埋めますchar array[100] = {0};か?その背後にある魔法は何ですか?

内部でコンパイラがどのように初期化されるのか知りたい。


1
CまたはC ++で?これらは2つの別個の質問です。
Toby Speight 2017年

回答:


163

それは魔法ではありません。

Cでのこのコードの動作は、C仕様のセクション6.7.8.21(C仕様のオンラインドラフト)で説明されています。指定された値を持たない要素の場合、コンパイラーはポインターをNULLに、算術型をゼロに初期化します(これを再帰的に集計に適用します)。

C ++でのこのコードの動作は、C ++仕様のセクション8.5.1.7(C ++仕様のオンラインドラフト)で説明されています。コンパイラは、指定された値を持たない要素を集約初期化します。

また、C ++(Cではない)では、空の初期化リストを使用できるため、コンパイラーが配列のすべての要素を集約初期化することに注意してください。

char array[100] = {};

これを行うとコンパイラーがどのようなコードを生成する可能性があるかについては、この質問を見てください:配列0からの奇妙なアセンブリ-初期化


すべてのCコンパイラはこれを行いますか?私はVisual Studioだけがこれを行うと信じていました。
JFA

1
c ++仕様のオンラインドラフトが壊れています。誰か新しいリンクがありますか?
Behrooz Karjoo 2017年

35

実装はコンパイラ開発者次第です。

あなたの質問が「そのような宣言で何が起こるか」である場合-コンパイラーは最初の配列要素を指定された値(0)に設定し、その他はすべて省略された配列要素のデフォルト値であるためゼロに設定されます。


ソースはありませんが、配列宣言にはデフォルト値がないことをどこかで読んだことは確かです。あなたはすでにそこにあったゴミを手に入れます。とにかく上書きする可能性が高いときに、これらの値の設定に時間を浪費しても意味がありません。
ライアンフォックス

10
Ryan、最初の要素に値を設定しない場合、配列全体が初期化されておらず、実際にガベージが含まれていますが、その少なくとも1つの要素に値を設定すると、配列全体が初期化され、指定されていない要素が暗黙的に初期化されます。 0.
qrdl 2009年

1
C ++の場合、有界配列の空の初期化リストはすべての要素をデフォルトで初期化します。
dalle

2
@NatanYellinこれは未定義だとどこで言ったのですか?コメントや投票を行う前に、回答全体をお読みください。
qrdl

1
@qrdlその通りです。実装についてのコメントを誤解しました。残念ながら、今は投票を変更できません。
Natan Yellin

27

コンパイラがGCCの場合は、次の構文も使用できます。

int array[256] = {[0 ... 255] = 0};

http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Initsを参照してください。これはコンパイラ固有の機能であることに注意して ください


ようこそ!あなたがより多くのそのような種類のトリックを探すことを求めたので、私は提供しました
lakshmanaraj '10年

1
選択すれば確かにこれを実行できますが、このようなコンパイラ固有の拡張機能に依存することには明らかな欠点があります。
ダン・オルソン

@Dan Olson彼自身の質問は、コンパイラ固有について質問しているため、これを投稿しています。役に立たないと思ったら削除します。
lakshmanaraj 2009年

5
それは役に立たないわけではありません、それは興味深いです。警告は注意するに値します。
Dan Olson

2
これは、私がSOに戻って、上位のいくつかの回答よりも多くを読んでいるようなものです
timday

19

この初期化をどこに置くかによります。

配列が静的である場合

char array[100] = {0};

int main(void)
{
...
}

次に、プログラムのデータセグメントで100 0バイトを予約するのはコンパイラです。この場合、イニシャライザを省略できます。

アレイが自動の場合、それは別の話です。

int foo(void)
{
char array[100] = {0};
...
}

この場合、関数fooを呼び出すたびに、memsetが非表示になります。

上記のコードは以下と同等です

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

イニシャライザを省略した場合、配列にはランダムデータ(スタックのデータ)が含まれます。

ローカル配列が次のように静的に宣言されている場合

int foo(void)
{ 
static char array[100] = {0};
...
}

その後、技術的には最初のケースと同じです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.