空的初始化列表是否为有效的C代码?

Mar*_*erg 35 c standards gcc struct initializer

通常用于{0}初始化a struct或a,array但考虑第一个字段不是标量类型时的情况.如果第一个字段struct Person是另一个struct或数组,则该行将导致错误(error: missing braces around initializer).

struct Person person = {0};
Run Code Online (Sandbox Code Playgroud)

至少GCC允许我使用空的初始化列表来完成同样的事情

struct Person person = {};
Run Code Online (Sandbox Code Playgroud)

但这是有效的C代码吗?

另外:这条线是否保证给出相同的行为,即零初始化struct

struct Person person;
Run Code Online (Sandbox Code Playgroud)

int*_*jay 40

不,不允许使用空的初始化列表.在编译时,GCC也可以显示-std=c99 -pedantic:

a.c:4: warning: ISO C forbids empty initializer braces
Run Code Online (Sandbox Code Playgroud)

原因是语法在2011 ISO C标准的 §6.7.9中定义的方式:

initializer:
         assignment-expression
         { initializer-list }
         { initializer-list , }
initializer-list:
         designation(opt) initializer
         initializer-list , designation(opt) initializer
Run Code Online (Sandbox Code Playgroud)

根据该定义,初始化列表必须包含至少一个初始化程序.

  • 这是正确的答案(语法禁止使用空的初始化列表).这有点不幸,如果标准允许它会很好,但它们一般不会真正允许空对象,因此不需要它.问题的其余部分的答案(如果有***= {...}`部分,你会得到如果为零)是"如果对象有静态持续时间则为是,否则为否". (5认同)
  • 这回答了我的问题.如果我不知道第一个成员的类型(如果结构声明是自动生成的情况),我仍然没有在单行初始化结构的万无一失的方法,但那是一个不同的问题. (2认同)

小智 18

是的,C23 允许空初始化。如果初始化器是空初始化器,则初始值与静态存储持续时间对象的初始化相同。

struct Person person = {}; // Valid C23
Run Code Online (Sandbox Code Playgroud)

如果一个对象是用空的初始化器初始化的,那么:

  • 如果是指针类型,则初始化为空指针

  • 如果它具有十进制浮点类型,则将其初始化为(正或无符号)零,并且量子指数是实现定义的166)

  • 如果它具有算术类型,并且它没有十进制浮点类型,则将其初始化为(正或无符号)零

  • 如果是聚合,则根据这些规则(递归地)初始化每个成员,并且任何填充都初始化为零位

  • 如果是联合,则根据这些规则(递归地)初始化第一个命名的成员,并且任何填充都初始化为零位

参考:ISO/IEC 9899:202x (E)


fun*_*man 6

根据 C99 标准,禁止使用空的初始化列表创建数组。在之前的回答中,您可以看到语法没有描述这种情况。


但是如果你声明一个没有初始化的数组会发生什么?好吧,这取决于您使用的编译器。让我们来看看这个简单的例子:int arr[5] = {}

海湾合作委员会

默认情况下gcc,当您尝试编译此代码时不会产生任何警告/错误。甚至没有-Wall,但-Wpedantic确实如此。

warning: ISO C forbids empty initializer braces
Run Code Online (Sandbox Code Playgroud)

但无论如何gcc,用 0 填充数组的成员,就像您明确指定它一样,int arr[5] = {0}请参阅程序集输出Godbolt

但默认情况下不显示有关这种情况的警告,但带有选项-Wgnu-empty-initializer

warning: use of GNU empty initializer extension
Run Code Online (Sandbox Code Playgroud)

Clang 生成不同的汇编代码Godbolt但行为相同。