int q = {1,2}; 奇特的初始化列表

我遇到了下面的初始化,可以看出VS2012显示错误,抱怨初始化程序太多。 在GCC中,它似乎返回第一个元素作为值。

为什么在GCC中支持这种特殊的初始化?

#include  int main() { int q = {1,2}; char c = {'s','t','\0'}; /* c is 's' */ printf("%d\n",q); /* prints 1*/ } 

C11:6.7.9初始化(第11页):

标量的初始值设定应为单个表达式, 可选择用大括号括起来

因此,这是允许的

 int q = {1}; 

您可以将标量对象的初始值设定项括在大括号( {} )中。 请注意,动词在此处使用。 标准说:

5.1.1.3诊断(P1):

如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合的实现应生成至少一个诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现 – 定义

因此,它取决于编译器如何处理

 int q = {1,2}; 

在GCC 4.8.1上使用标志-pedantic -Wall -Wextra并发出警告

 [Warning] excess elements in scalar initializer [enabled by default] 

现在的问题是: 剩余的初始化器发生了什么? 这是一个错误 。


注意: C11:6.5.17(p3)表示逗号运算符不能出现在使用逗号分隔列表中的项目的上下文中(例如函数的参数或初始值设定项列表)。

不要混淆{1,2}中的逗号运算符 。 正如Keith Thompson指出的那样,初始化器中的表达式赋值表达式,并且它不能包含顶层的逗号运算符 。 这意味着它可以在带括号的表达式中使用,也可以在这种上下文中的条件运算符的第二个表达式中使用。 在函数调用中

 f(a, (t=3, t+2), c) 

该函数有三个参数,第二个参数的值为5