【问题标题】:Why is {0} always a valid struct initializer? [duplicate]为什么 {0} 始终是有效的结构初始化程序? [复制]
【发布时间】:2020-12-04 01:41:05
【问题描述】:

考虑以下 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 是一个数组,而不是一个标量。如果我用1 替换0,这会立即产生预期的警告消息:

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

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

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

【问题讨论】:

    标签: c struct initializer


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

    • = {0} 是表达的理想方式:“请零初始化此对象。”如果可以,我们会将大括号留空,但不幸的是,= {} 不是合法的 C 代码,因此必须添加 0
    • 我相信这个答案错过了问题的全部要点。我没有写 {{0}} 来初始化结构内的数组。但是我写了{0}
    猜你喜欢
    • 2016-02-22
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 2011-12-24
    • 2021-07-19
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多