【问题标题】:Storage Duration and Member Initialization of a Struct in C++C++中结构的存储持续时间和成员初始化
【发布时间】:2017-05-26 13:12:35
【问题描述】:
#include <iostream>

using namespace std;

struct A {
    // Some Other Code
    int x;
};

A a1;

int main(){
    A a2;
    cout << "a1.x = " << a1.x << endl;
    cout << "a2.x = " << a2.x << endl;
    return 0;
}

C++14 标准 (ISO/IEC 14882:2014) 第 8.5 节第 12 段:

如果没有为对象指定初始化程序,则该对象是默认初始化的。当获得具有自动或动态存储持续时间的对象的存储时,该对象具有不确定值,如果没有对对象执行初始化,则该对象将保留一个不确定值,直到该值被替换( 5.17)。 [ 注意:具有静态或线程存储持续时间的对象是零初始化的,请参见 3.6.2。 - 尾注]

a1 有静态存储持续时间,a2 有自动存储持续时间吗? Struct A 的定义在全局命名空间中,a1 声明也是如此,而 a2 声明在块范围内(在 main() 函数内)。

另外,第 3.6.2 节说:

第 1 段:

具有静态存储持续时间的非局部变量被初始化 作为程序启动的结果。

第 2 段:

具有静态存储持续时间 (3.7.1) 或线程存储持续时间 (3.7.2) 的变量应在进行任何其他初始化之前进行零初始化 (8.5)。

此外,使用 gcc 5.4.0 我会收到警告 (warning: 'a2.A::x' is used uninitialized in this function [-Wuninitialized]) 和随机值,但使用 clang 3.8.0 时输出始终为 a2.x = 0(零也可以是不确定的值)。我还做了其他更复杂的实验,嵌套的structs 和默认的初始化放在// Some Other Code。有时我得到随机值,而其他时候(不是可忽略的数量)我得到一个零。

  • 结构A 的存储持续时间是多少?对象a1a2 呢?变量a1.xa2.x 呢?

  • 应该将a1.xa2.x 初始化为零吗?还是它们是不确定的值?

  • 相同的规则是否适用于classunion

  • // Some Other Code 中的代码有什么不同吗?例如,如果一个类 T “具有带有默认初始化程序的非静态成员”(如 struct A { int b = 1; int x; }; 中),则默认构造函数不能是微不足道的(即不能不执行任何操作)。那个不平凡的构造函数也会初始化x吗? Trivial Default Constructor

有趣的链接:

C++ Structure Initialization

Initializing default values in a struct

Are members of a C++ struct initialized to 0 by default?

Default initialization of POD types in C++

Initialization of Objects with Static Storage Duration in C vs C++

C and C++ : Partial initialization of automatic structure

How to initialize structures to all-elements-zero-or-null

【问题讨论】:

  • a1 是默认初始化的,a2 不是。
  • 我回答了你的问题,除了最后一个,因为我觉得不清楚。你能改写一下吗?
  • @VittorioRomeo 你说得对,对不起,这点没有解释清楚,我只是编辑了它。我的问题是,一个重要的构造函数是否也会初始化(¿零初始化?)结构中没有默认初始化器的剩余成员。谢谢。

标签: c++ struct initialization member storage-duration


【解决方案1】:

那么 a1 有静态存储持续时间,a2 有自动存储持续时间吗?

Struct A 的定义在全局命名空间...

这无关紧要。

... 在全局命名空间中,以及a1 声明

a1 具有静态存储持续时间,并且是零初始化的。

a2 声明在块范围内

a2 是一个非静态块局部变量。它具有自动存储持续时间,并且默认初始化。它有一个不确定的值。


structA的存储时长是多少?

类型没有存储期限。对象可以。

...a1a2 的对象呢?

见上文。

.. 变量a1.xa2.x

子对象,包括非静态数据成员,继承其超级对象的生命周期。

... a1.xa2.x 应该被零初始化吗?还是它们是不确定的值?

a1 初始化为零。这包括它的子对象。 a2 不是。这包括它的子对象。

相同的规则适用于类和联合吗?

当涉及到存储类时,相同的规则集适用于联合和非联合类的对象以及非类类型。不同类型的默认初始化含义有所不同。

// Some Other Code 中的代码有什么不同吗?例如,如果类 T 的构造函数“具有带有默认初始化程序的非静态成员”,则默认构造函数不能是微不足道的(即不执行任何操作)。

由编译器默认生成的非平凡默认构造函数初始化没有默认初始化器的成员。

【讨论】:

  • 关于您的最后一个答案:您的意思是非平凡的默认构造函数(编译器生成)会将x 初始化为某个值吗?还是您指的是在代码中显式初始化x 的非平凡用户定义构造函数?我显然会理解后者,但不是前者。谢谢。
  • @JL 实际上,我错了。非平凡的默认构造函数不一定要初始化所有成员。我已经编辑了答案。
【解决方案2】:

结构 A 的存储期限是多少?

这个问题没有意义,存储取决于A的使用方式。


对象 a1 和 a2 呢?

a1 具有静态存储。 See this question for more details.

a2 具有自动存储功能。


变量 a1.x 和 a2.x 呢?

它们的存储方式与其父 A 实例相同。


相同的规则适用于类和联合吗?

是的。

【讨论】:

    猜你喜欢
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-19
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多