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

bar*_*tal 29 c

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

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

#include <stdio.h>

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

hac*_*cks 37

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

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

因此,这是允许的

int q = {1};   
Run Code Online (Sandbox Code Playgroud)

您可以在标量({})中包含标量对象的初始值设定项.注意动词应该用在这里.标准说:

5.1.1.3诊断(P1):

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

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

int q = {1,2}; 
Run Code Online (Sandbox Code Playgroud)

在带有标志的GCC 4.8.1上编译-pedantic -Wall -Wextra并发出警告

[Warning] excess elements in scalar initializer [enabled by default]   
Run Code Online (Sandbox Code Playgroud)

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


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

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

f(a, (t=3, t+2), c)
Run Code Online (Sandbox Code Playgroud)

该函数有三个参数,第二个参数具有值5.