提问人:Karolis Milieška 提问时间:9/6/2018 最后编辑:Some programmer dudeKarolis Milieška 更新时间:9/6/2018 访问量:968
自动存储持续时间结构初始化
Automatic storage duration struct initialization
问:
其中一些可能是重复的,但我对此感到抱歉。
假设我有这个:struct
struct foo
{
int a;
int b;
int c;
};
1. 如果类型对象以具有自动存储持续时间且没有初始值设定项的方式声明,是否可以保证它的所有成员都将强制初始化为零?struct foo
{
// other stuff
struct foo bar;
// other stuff
}
2. 如果类型对象以具有自动存储持续时间的方式声明,并且带有一些初始值设定项,是否可以保证未显式初始化的成员将被强制初始化为零?struct foo
{
// other stuff
struct foo bar = {.a = 1};
// other stuff
}
3. 如果类型对象以具有自动存储持续时间的方式声明,并且使用复合文字表达式,是否可以保证未显式初始化的成员将被强制初始化为零?struct foo
{
// other stuff
func((struct foo){.a = 1});
// other stuff
}
任何 C 标准参考都非常感谢!谢谢!
答:
首先,具有自动存储功能的未初始化变量将永远不会被初始化。摘自 C11 标准 (ISO/IEC 9899:2011 §6.7.9/10):
如果未显式初始化具有自动存储持续时间的对象,则其值不确定。
然后从这个结构初始化参考:
所有未显式初始化的成员的隐式初始化方式与具有静态存储持续时间的对象相同。
如果我们遵循“隐式初始化”链接,我们有:
具有静态和线程本地存储持续时间的对象初始化如下
- ...
- 整数类型的对象初始化为无符号零
- ...
因此,为了回答您的问题:
- 不,没有初始化,因为您的代码中没有显式初始化(请参阅标准中的引文)
- 是的,因为这是一个结构初始化
- 是的,原因与 2 相同。
提供的链接引用了该标准。
评论
摘要,TL;博士:
存储期限说明:
- 在函数中声明的变量具有自动存储持续时间(包括函数的参数)。
- 声明为 的变量或在文件范围(“global”)外部声明的变量具有静态存储持续时间。
static
结构(和数组)初始化说明:
- 如果未初始化任何成员,并且结构具有自动存储持续时间,则不会初始化任何内容。
- 如果未初始化任何成员,并且结构具有静态存储持续时间,则所有成员都将初始化为零。
- 如果初始化任何成员,则未接触的成员将初始化为零。
C标准(C17 6.7.9 §10)的相关部分:
如果未显式初始化具有自动存储持续时间的对象,则其值不确定。如果具有静态或线程存储持续时间的对象未显式初始化,则:
- 如果它具有指针类型,则将其初始化为 null 指针;
- 如果它具有算术类型,则初始化为(正或无符号)零;
- 如果它是一个聚合,则每个成员都根据这些规则进行初始化(递归),并且任何 填充初始化为零位;
其中“artihmetic type”是普通变量(如 )的标准乱码,而“aggregate”是数组和结构的标准乱码。int
在同一章的后面(C17 6.7.9 §19):
...所有未显式初始化的子对象都应与具有静态存储持续时间的对象一样隐式初始化。
问题解答:
- 如果 struct foo 类型对象以具有自动存储持续时间且没有初始值设定项的方式声明,是否可以保证它的所有成员都将强制初始化为零?
不,不能保证;如上面引文的第一句话所述,它们的值是不确定的。
- 如果 struct foo 类型对象以具有自动存储持续时间的方式声明,并且带有一些初始值设定项,是否可以保证未显式初始化的成员将被强制初始化为零?
是的,根据上面引用的 C17 6.7.9 §19。
- 如果 struct foo 类型对象以具有自动存储持续时间的方式声明,并且使用复合文本表达式,是否可以保证未显式初始化的成员将强制初始化为零?
是的,由于复合文字是数组或结构,因此它们遵循相同的初始化规则。
评论