2012-03-20 8 views
47

redditにこのコードがあります。私は型変換によってこれが無効になったと思っていたでしょう。なぜこれが有効なのですか

int a[3] = { { {1, 2}, {3, 4}, 5, 6 }, {7, 8}, {9}, 10 }; 

clangでは、スカラー初期化子の余分な要素と中カッコについて警告が表示されます。しかしaの内容は[1, 7, 9]です。

これは実際に正当なものですか、そうであれば、誰かが正確に何が起こっているのか説明できますか?

+5

+1、真剣に面白いです。 – ApprenticeHacker

+4

gccで24件の警告が表示されます。素晴らしい質問。私は生きて&学ぶ:-) – gbulmer

+1

よろしくgcc!少なくともあなたは警告を受ける。 – boatcoder

答えて

28

超過要素は無視されます。あなたが気にしている6.7.8初期化の2つの部分があります。まず、段落17から:

各中括弧付きイニシャライザリストには、現在のオブジェクトが関連付けられています。指定がない場合、現在のオブジェクトのサブオブジェクトは、現在のオブジェクトの型に従って順番に初期化されます。添字順の配列要素、宣言順の構造体メンバ、およびユニオンの最初の名前付きメンバです。

なぜ、あなたが1、7、9を得るのかを説明すると、現在のオブジェクトはそれらの中カッコによって設定されます。そして、それは、段落20から、余分な気にしない理由として:

...リストから必要なだけの初期化子はsubaggregateかの最初のメンバーの要素またはメンバーを説明するために取られています組合を含む。残っているイニシャライザは、現在の部分集合または含まれる集合が一部である集合体の次の要素またはメンバを初期化するために残されます。

+0

しかし、なぜですか?そして構造体/共用体/クラス型がない場合にネストした要素を渡すのはなぜ有効ですか? – ams

+1

引用している標準のURLを共有してもよろしいですか? – dldnh

+0

[PDFリンク。](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf) –

2
int a[3] = { { {1, 2}, {3, 4}, 5, 6 }, {7, 8}, {9}, 10 }; 

無効です。

それは同じ理由int b[1] = {1, 2};ため無効であるが無効です:C99は

を言うので(C99、6.7.8p1)「いいえ初期化子が初期化されたエンティティ内に含まれていないオブジェクトの値を提供しようとしてはなりません" aイニシャライザで

最後の要素10が初期化されるエンティティ内に含まれていないオブジェクトの値を提供することを試みます。

+0

私は、あなたが引用したリファレンスとCarl氏が引用した第2の参考文献の異なるアサーションについての良い議論を聞きたいです。標準内で明確な矛盾が生じていると思われます。これにより、コンパイラの実装が解決されるまでの間に違いが生じる可能性があります。 diffを指摘するための+1。 – ryyker

関連する問題