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

这通常被建议,作为将结构体初始化为零值的方法
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作为任何类型的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 */

解决方法

是的,这是完全有效的.

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

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

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

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...