【问题标题】:Automatic storage duration struct initialization自动存储持续时间结构初始化
【发布时间】:2019-02-11 18:32:29
【问题描述】:

其中一些可能是重复的,但我很抱歉。
假设我有这个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 initialization language-lawyer automatic-storage


    【解决方案1】:

    总结,TL;DR

    存储时间说明:

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

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

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

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

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

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

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

    在同一章的进一步下方(C17 6.7.9 §19):

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


    回答您的问题:

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

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

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

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      然后来自this structure initialization reference

      所有未显式初始化的成员都是initialized implicitly,与具有静态存储持续时间的对象相同。

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

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

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

      所以回答你的问题:

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

      提供的链接参考了标准。

      【讨论】:

      • @ryyker 不是,因为 1 不是结构初始化。对于初始化,您需要实际初始化变量。
      • 我已经检查了 C 参考中的同一个地方,但这并没有说明结构的主要声明的存储持续时间。这让我不确定。 “所有未显式初始化的成员都以与具有静态存储持续时间的对象相同的方式进行隐式初始化。”这是否意味着这适用于静态和汽车?
      • @ryyker 一旦你初始化了 any 对象,那些你不接触的对象就会被隐式初始化。但是,如果您初始化 no 对象(自动存储结构的),则不会初始化任何对象。
      • @KarolisMilieška 不,任何具有自动存储持续时间的未初始化对象都保持未初始化状态。添加了标准的报价。对于数字 2 和 3,有一个显式(结构)初始化会改变语义。
      • @Someprogrammerdude 最后的评论不正确。无论程序员做什么,具有静态存储持续时间的未初始化对象总是被初始化。
      猜你喜欢
      • 2017-05-26
      • 1970-01-01
      • 2021-02-08
      • 2020-02-17
      • 2016-11-06
      • 2018-04-15
      • 1970-01-01
      • 2011-01-25
      • 1970-01-01
      相关资源
      最近更新 更多