为什么这个有效的C.

我在reddit上遇到了这个代码。 我会认为,types转换会导致这是无效的。

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

在叮当中,我在标量初始值设定中得到了一些关于过量元素和大括号的警告。 但是a的内容是[1, 7, 9]

这实际上是合法的,如果是这样,有人可以解释究竟是怎么回事?

多余的元素被忽略。 有6.7.8初始化 ,你在乎的两个部分。 首先从第17段开始:

每个括号包围的初始化程序列表都有一个关联的当前对象。 当不存在指定时,根据当前对象的types对当前对象的子对象进行初始化:按照下标顺序递增的数组元素,按照声明顺序的结构成员以及联合的第一个指定成员。

那一个解释了为什么你会得到1,7和9 – 当前的对象被大括号设置。 那么为什么它不关心额外的问题呢,从第20段来看:

…只有足够的名单中的初始化者才能考虑子集团的要素或成员或所包含工会的第一个成员; 任何剩余的初始化器都将被初始化为当前子集合或包含的联合所属的集合的下一个元素或成员。

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

是无效的。

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

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

初始化器中的最后一个元素10试图为未被包含在被初始化的实体内的对象提供一个值。