首页 > 解决方案 > 为什么 {0} 始终是有效的结构初始化程序?

问题描述

考虑以下 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将表示 member 的初始化程序a。但是a是一个数组,而不是一个标量。如果我01这个替换它会立即产生预期的警告消息:

warning: missing braces around initializer [-Wmissing-braces]
   14 | abc_t x = { 1 };
      |           ^
      |             { }

C 标准中是否有一些例外{ 0 }总是被解释为将所有内容设置为零的初始化程序?常见的文档来源似乎没有讨论类型的明显不匹配(数组与标量)。

我知道初始化程序不能为空,即{ }不是有效的初始化程序。

标签: cstructinitializer

解决方案


为什么 {0} 始终是有效的结构初始化程序?

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

C 标准中是否存在一些例外,即 { 0 } 总是被解释为将所有内容设置为零的初始化程序?

不,没有区别。文件范围内没有显式初始化的任何变量始终初始化为零或指向 NULL。有关参考,请参阅cppreference 初始化

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

= {1}第一个数组元素的情况下将被显式初始化为一个。其余的数组元素和其余的结构成员被隐式初始化为零。哦,您的编译器也恰好发出警告,这是“实施质量”的事情。

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


推荐阅读