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)
根据该定义,初始化列表必须包含至少一个初始化程序.
小智 18
是的,C23 允许空初始化。如果初始化器是空初始化器,则初始值与静态存储持续时间对象的初始化相同。
struct Person person = {}; // Valid C23
Run Code Online (Sandbox Code Playgroud)
如果一个对象是用空的初始化器初始化的,那么:
如果是指针类型,则初始化为空指针
如果它具有十进制浮点类型,则将其初始化为(正或无符号)零,并且量子指数是实现定义的166)
如果它具有算术类型,并且它没有十进制浮点类型,则将其初始化为(正或无符号)零
如果是聚合,则根据这些规则(递归地)初始化每个成员,并且任何填充都初始化为零位
如果是联合,则根据这些规则(递归地)初始化第一个命名的成员,并且任何填充都初始化为零位
参考:ISO/IEC 9899:202x (E)
根据 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但行为相同。