C 为什么{0}始终是有效的结构初始值设定项?

C 为什么{0}始终是有效的结构初始值设定项?,c,struct,initializer,C,Struct,Initializer,考虑以下C代码: typedef struct abc { int a[4]; int b; int c; } abc_t; abc_t x = { 0 }; 我发现将其与gcc-c-Wall-Wextra-pedantic-std=c99进行比较不会产生任何警告或错误消息。我的解释是0将表示成员a的初始值设定项。但是a是数组,而不是标量。如果我将0替换为1,则会立即产生预期的警告消息: warning: missing braces around initializer [-W

考虑以下C代码:

typedef struct abc {
  int a[4];
  int b;
  int c;
} abc_t;

abc_t x = { 0 };
我发现将其与gcc-c-Wall-Wextra-pedantic-std=c99进行比较不会产生任何警告或错误消息。我的解释是
0
将表示成员
a
的初始值设定项。但是
a
是数组,而不是标量。如果我将
0
替换为
1
,则会立即产生预期的警告消息:

warning: missing braces around initializer [-Wmissing-braces]
   14 | abc_t x = { 1 };
      |           ^
      |             { }
在C标准中是否有一些例外情况,
{0}
总是被定义为初始值设定项,它将所有内容设置为零?许多文档似乎没有讨论类型的明显不匹配(数组与标量)

我知道初始值设定项不能为空,即
{}
不是有效的初始值设定项

为什么{0}始终是有效的结构初始值设定项

因为语法允许。它允许省略大括号来初始化子聚合

在C标准中是否有例外{0}总是被解释为将所有内容设置为零的初始值设定项

不,没有区别。文件作用域中没有显式初始化的任何变量总是初始化为零或指向NULL的指针。有关参考,请参阅

唯一的区别是警告的存在和第一个数组元素的值。在
={0}
的情况下,第一个数组元素将显式初始化为零,其余数组元素和其余结构成员将隐式初始化为零

={1}
的情况下,第一个数组元素将显式初始化为1。其余的数组元素和其余的结构成员被隐式初始化为零。Och,并且您的编译器碰巧也会发出警告,这就是“实现质量”问题


={0}
是一种常见的代码,程序员不关心大括号是否签出,因此,作为一个高质量的编译器,您的编译器不想打扰程序员在这种情况下忘记大括号。如果你想让你的编译器在这种情况下发出警告,你知道答案-资助你的编译器开发,创建一个功能请求和/或贡献给社区,并实现一个新的类似
-Wmissing的大括号,当零警告时也是如此。

={0}
是一种表意的表达方式:“请零初始化此对象。”如果可以,我们会将大括号留空,但不幸的是,
={}
不是合法的C代码,因此必须添加
0
。我相信这个答案没有抓住问题的关键。我没有编写将初始化结构内部数组的
{0}
。但我编写了
{0}