c - 标准 C 是否接受 `{0}` 作为任何结构的初始值设定项?

标签 c struct initialization language-lawyer

这通常被建议,作为将结构初始化为零值的一种方式:

struct foo f = {0};

还提到 {} 可以在 gcc 下使用,但这不是标准的 C99。

我想知道这是否适用于布局可能超出我控制范围的结构。我很着急,因为 0 不是数组或结构的有效初始值设定项。然而,即使在这种情况下,gcc --std=c99 (gcc-8.1.1-1.fc28.x86_64) 似乎也接受 {0}

问题 C99 是否接受{0} 作为任何结构的初始值设定项?

(或后来的 C 标准?或者相反,是否有任何理由不依赖于此?是否存在编译器,其中 {0} 可能会导致错误或警告,从而阻止其使用? )

我尝试过的

gcc 警告(通过 -Wall 启用)表明这是标准中的某种形式的边缘情况,其中 gcc 被迫接​​受 0 作为任何类型的结构字段,但除非您使用常见的 {0} 习惯用法,否则它会发出警告。

struct a { int i; };
struct b { struct a a; struct a a2; };
struct c { int i[1]; int j[1]; };

struct a a = {0}; /* no error */
struct b b = {0}; /* no error */
struct c c = {0}; /* no error */

/* warning (no error): missing braces around initializer [-Wmissing-braces] */
struct b b2 = {0, 0};
/* warning (no error): missing braces around initializer [-Wmissing-braces] */
struct c c2 = {0, 0};

struct a a2 = 0; /* error: invalid initializer */
int i[1] = 0; /* error: invalid initializer */

最佳答案

是的,这是完全正确的。

所有标量类型(整数类型、浮点类型和指针类型)都接受 0 作为初始化程序。这不是标量类型的基本属性,但恰好适用于所有标量类型。

所有聚合类型(数组和结构)和 union 类型都至少有一个成员或元素。第一个成员或元素是标量类型,或者是另一种聚合或 union 类型。如果是前者,则 {0} 成为有效的初始化程序。如果是后者,应用相同的逻辑:那也将至少有一个成员或元素。 that 要么是标量类型,要么是另一种聚合或 union 类型。继续。没有办法拥有无限嵌套的结构,因此您将始终以标量类型结束。

非标准语言扩展可能会使其中一些假设无效。例如,语言扩展可以定义不接受 0 作为初始化程序、空结构或零长度数组的强类型枚举类型。

关于c - 标准 C 是否接受 `{0}` 作为任何结构的初始值设定项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50908313/

相关文章:

c - 在 Linux 机器上获取用户的默认电子邮件

c - 有没有办法让结构的某些成员不可修改?

c++ - 动态分配的对象是否默认初始化?

c++ - 编译时检查以确保结构中的任何地方都没有填充

c - 局部变量与全局变量

c++ - 放置新的和未初始化的 POD 成员

c - 两个 unsigned long 变量相减结果为零,即使它们的值不同

c - 这个函数的错误处理有问题吗?

c - 学习如何在使用 scanf 时正确引用结构体字段 (C)

swift - 如何在 Swift 中将结构声明为 typealias 的返回类型