C中的数组初始化

vol*_*aa7 19 c c++ arrays

我对以下代码有疑问:

int main()
{
    int array1 = {1,2,3,4,5}; //error in c++ , warning in c
    int array2[] = {1,2,3,4,5};
    int array3[5] = {1,2,3,4,5};
}
Run Code Online (Sandbox Code Playgroud)

这段代码在第3行给出错误c++但不在c

我知道array1其实是一个intarray2array3是数组,那么为什么没有一个c编译器显示一个错误,但只是一个警告:"在标量初始化多余元素"

是否使用了这样的定义,为什么它有效c

Lun*_*din 26

它无效C.见C11 6.7.9:

初始化程序不应尝试为未初始化的实体中包含的对象提供值.

我猜你正在使用gcc.然后,如果您希望程序的行为与严格的标准C一样,请按以下方式编译:

gcc -std=c11 -pedantic-errors
Run Code Online (Sandbox Code Playgroud)

错误:标量初始化程序中的多余元素

  • 这是一个约束违规,即使没有`-pedantic-errors`,gcc也能正确地发出诊断信息,就ISO C而言,这个问题非常严格.拒绝代码不需要实现. (4认同)
  • @BlueMoon那是因为标准中没有警告和错误之类的东西.对于程序员来说,错误更好. (2认同)

Bal*_*ckk 15

是不是有效的C.它只是对代码少检查.这是未定义的行为.

来自:C11草案N1570; 6.7.9初始化

约束
2初始化程序不应尝试为未初始化的实体中包含的对象提供值.
3要初始化的实体的类型应为未知大小的数组或不是可变长度数组类型的完整对象类型.

绝对打破约束2.是int一个完整的对象类型

附件J.2(未定义的行为):

标量的初始值设定项既不是单个表达式,也不是括在括号中的单个表达式(6.7.9).

额外:
@James Kanze:

prog.c:4:12: error: expected identifier or ‘(’ before numeric constant
  int i = 1,2,3,4,5;
            ^
Run Code Online (Sandbox Code Playgroud)

你可以做到,但你需要做一个表达式:

int i = (1,2,3,4,5); //need parenthesis, evaluates to 5, values 1-4 thrown away.
Run Code Online (Sandbox Code Playgroud)

使用int初始化的initalizer-list进行编译会产生警告(在gcc中):

prog.c:5:2: warning: excess elements in scalar initializer [enabled by default]
  int j = {1,2,3,4,5};
  ^
Run Code Online (Sandbox Code Playgroud)

但似乎编译器足够聪明,只能初始化int而不是以下内存. demo

  • 不确定约束违规会导致未定义的行为.C标准是否表明或暗示? (2认同)
  • 但是`{1,2,3,4,5}!= 1,2,3,4,5`.前者是初始化列表,后者是逗号运算符的5个不同值.我认为这适用:`标量的初始化程序既不是单个表达式也不是括在括号中的单个表达式(6.7.9).如果错误请纠正我 (2认同)

Som*_*ude 11

它符合C规范.

引自C11第6.7.9节(初始化):

句法

1 initializer:
    assignment-expression
    { initializer-list }
    { initializer-list , }
Run Code Online (Sandbox Code Playgroud)

因此初始化程序可以是直接表达式(assignment-expression上面),也可以是括号括起来的初始化程序列表.标准的该部分中的约束不限制"正常"(非数组或非指针)变量.

这允许你写例如

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

  • 但是,在提到的语法下面的第一个规范性文本呢?`没有初始化器应该尝试为未被初始化的实体中包含的对象提供值.你引用的语法确实允许`int a = {1}`但这并不意味着`int array1 = {1,2 ,3,4,5};`是允许的,出于同样的原因它不允许`int array1 [1] = {1,2,3,4,5};` (9认同)
  • 引用没有约束的语法实际上并没有说出足够的故事,这实际上只是答案的一半,文本中的约束对于这个问题很重要. (4认同)