自动存储持续时间结构初始化

Automatic storage duration struct initialization

提问人:Karolis Milieška 提问时间:9/6/2018 最后编辑:Some programmer dudeKarolis Milieška 更新时间:9/6/2018 访问量:968

问:

其中一些可能是重复的,但我对此感到抱歉。
假设我有这个:
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 标准参考都非常感谢!谢谢!

c struct 初始化 语言-lawyer 自动存储

评论


答:

2赞 Some programmer dude 9/6/2018 #1

首先,具有自动存储功能的未初始化变量将永远不会被初始化。摘自 C11 标准 (ISO/IEC 9899:2011 §6.7.9/10):

如果未显式初始化具有自动存储持续时间的对象,则其值不确定。

然后从这个结构初始化参考

所有未显式初始化的成员的隐式初始化方式与具有静态存储持续时间的对象相同。

如果我们遵循“隐式初始化”链接,我们有:

具有静态和线程本地存储持续时间的对象初始化如下

  • ...
  • 整数类型的对象初始化为无符号零
  • ...

因此,为了回答您的问题:

  1. 不,没有初始化,因为您的代码中没有显式初始化(请参阅标准中的引文)
  2. 是的,因为这是一个结构初始化
  3. 是的,原因与 2 相同。

提供的链接引用了该标准。

评论

1赞 Some programmer dude 9/6/2018
@ryyker 不是真的,因为 1 不是结构初始化。对于初始化,您需要实际初始化变量。
0赞 Karolis Milieška 9/6/2018
我已经检查了 C 引用中的相同位置,但这并没有说明结构主声明的存储持续时间。这让我不确定。“所有未显式初始化的成员的隐式初始化方式与具有静态存储持续时间的对象相同。”这是否意味着这适用于静态和自动?
3赞 Lundin 9/6/2018
@ryyker 一旦你初始化了任何对象,那些你不接触的对象就会被隐式初始化。但是,如果未初始化任何对象(自动存储结构),则不会初始化任何对象。
0赞 Some programmer dude 9/6/2018
@KarolisMilieška 否,任何具有自动存储持续时间的未初始化对象都将保持未初始化状态。添加了标准中的引用。对于数字 2 和 3,有一个显式(结构)初始化,它改变了语义。
0赞 Lundin 9/6/2018
@Someprogrammerdude 最后一条评论是不正确的。无论程序员做什么,具有静态存储持续时间的未初始化对象始终被初始化。
5赞 Lundin 9/6/2018 #2

摘要,TL;博士

存储期限说明:

  • 在函数中声明的变量具有自动存储持续时间(包括函数的参数)。
  • 声明为 的变量或在文件范围(“global”)外部声明的变量具有静态存储持续时间。static

结构(和数组)初始化说明:

  • 如果未初始化任何成员,并且结构具有自动存储持续时间,则不会初始化任何内容。
  • 如果未初始化任何成员,并且结构具有静态存储持续时间,则所有成员都将初始化为零。
  • 如果初始化任何成员,则未接触的成员将初始化为零。

C标准(C17 6.7.9 §10)的相关部分:

如果未显式初始化具有自动存储持续时间的对象,则其值不确定。如果具有静态或线程存储持续时间的对象未显式初始化,则:

  • 如果它具有指针类型,则将其初始化为 null 指针;
  • 如果它具有算术类型,则初始化为(正或无符号)零;
  • 如果它是一个聚合,则每个成员都根据这些规则进行初始化(递归),并且任何 填充初始化为零位;

其中“artihmetic type”是普通变量(如 )的标准乱码,而“aggregate”是数组和结构的标准乱码。int

在同一章的后面(C17 6.7.9 §19):

...所有未显式初始化的子对象都应与具有静态存储持续时间的对象一样隐式初始化。


问题解答:

  1. 如果 struct foo 类型对象以具有自动存储持续时间且没有初始值设定项的方式声明,是否可以保证它的所有成员都将强制初始化为零?

不,不能保证;如上面引文的第一句话所述,它们的值是不确定的。

  1. 如果 struct foo 类型对象以具有自动存储持续时间的方式声明,并且带有一些初始值设定项,是否可以保证未显式初始化的成员将被强制初始化为零?

是的,根据上面引用的 C17 6.7.9 §19。

  1. 如果 struct foo 类型对象以具有自动存储持续时间的方式声明,并且使用复合文本表达式,是否可以保证未显式初始化的成员将强制初始化为零?

是的,由于复合文字是数组或结构,因此它们遵循相同的初始化规则。