标准C是否接受`{0}`作为任何结构的初始化器?

sou*_*edi 6 c struct initialization language-lawyer

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

struct foo f = {0};
Run Code Online (Sandbox Code Playgroud)

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

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

问题 C99是否接受{0}任何结构的初始化程序?

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

我试过了什么

gcc警告(启用-Wall)表明这是标准中的某种形式的边缘情况,其中gcc被强制接受0作为任何类型的struct字段的初始化器,但它会警告它,除非你使用常见的{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 */
Run Code Online (Sandbox Code Playgroud)

小智 6

是的,这是完全有效的.

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

所有聚合类型(数组和结构)和联合类型都至少有一个成员或元素.第一个成员或元素是标量类型,或者是另一个聚合或联合类型.如果是前者,那就是{0}一个有效的初始化者.如果是后者,则应用相同的逻辑:也将至少有一个成员或元素.无论是标量型,或者是另一种聚集或联合类型.继续.没有办法拥有无限嵌套的结构,所以你总是会以标量类型结束.

非标准语言扩展可能会使这些假设无效.例如,语言扩展可以定义强类型枚举类型,它们不接受0初始化,空结构或零长度数组.