为什么这是有效的C.

时间:2012-03-20 17:44:09

标签: c

我在reddit上看到了这段代码。我原以为类型转换会导致这种情况无效。

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

在clang上,我得到一些关于标量初始化器中过多元素和大括号的警告。但a的内容为[1, 7, 9]

这是否合法,如果是,有人可以解释究竟发生了什么吗?

2 个答案:

答案 0 :(得分:28)

多余的元素被忽略了。您关注的是 6.7.8初始化两部分。首先,来自第17段:

  

每个大括号括起的初始化列表都有一个关联的当前对象。当没有指定时,根据当前对象的类型按顺序初始化当前对象的子对象:增加下标顺序的数组元素,声明顺序中的结构成员,以及union的第一个命名成员。

那个解释了为什么得到1,7和9 - 当前对象被这些括号设置。那么为什么它不关心附加内容,来自第20段:

  

...列表中只有足够的初始值设定项来考虑子聚合的元素或成员或所包含的联合的第一个成员;任何剩余的初始值设定项都用于初始化当前子聚合或包含的union所属的聚合的下一个元素或成员。

答案 1 :(得分:2)

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

无效。

由于int b[1] = {1, 2};无效的原因,它无效:因为C99说

  

(C99,6.7.8p1)“没有初始化程序应尝试为未初始化的实体中包含的对象提供值。”

10初始值设定项中的最后一个元素a尝试为未初始化的实体中包含的对象提供值。