是否保证默认构造函数将内置类型自动初始化为 0?

Is it guaranteed that defaulted constructor initialize built in types automatically to 0?

在你开始将其标记为重复之前,我已经阅读过 this .但它没有回答我的问题。链接的问题讨论的是 C++98 和 C++03,但我的问题是关于 C++11 引入的 defaulted constructor

考虑以下程序(查看现场演示 here):

#include <iostream>
struct Test
{
    int s;
    float m;
    Test(int a,float b) : s(a),m(b)
    { }
    Test()=default;
}t;
int main()
{
    std::cout<<t.s<<'\n';
    std::cout<<t.m<<'\n';
}

我的问题是编译器在这里提供的默认构造函数总是在 C++11 和 C++14 中将内置类型默认初始化为 0,当它们是 classstruct 时成员。 C++11 标准保证这种行为吗?

出于所有目的:

Test() = default;

相当于:

Test() {}

因此它不会初始化内置类型的成员。

不,默认构造函数什么都不做! 要初始化成员变量,您可以这样写:

struct Test
{
    int s = 0;
    float m = 3.3;
    Test(int a,float b) : s(a),m(b)
    { }
    Test()=default;
};

看看这个:C++ ctor = default

这个问题内置了两个单独的问题。

  1. 默认构造函数的= default是什么意思?来自 [class.ctor]:

    A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.

    也就是说,Test() = default 完全等同于 Test() { },它将默认初始化 sm,将它们设置为某个不确定的值。

  2. t.st.m是如何初始化的?是的,这是与 (1) 不同的问题,因为我们不只是在这里调用默认构造函数。来自 [basic.stc.static]:

    All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration.

    来自[basic.start.init]:

    Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.

    因此 t.st.m 保证为 0,即使我们默认构造一个本地 Test,它们也不会是。

Test = default 将默认初始化其成员。 但对于 intfloat 类型,默认初始化不同于值初始化

所以

Test t; // t.s and t.m have unitialized value

Test t{}; // t.s == 0 and t.m == 0.0f;

因为已经回答了,所以不能保证默认构造函数会 "initialize built in types automatically to 0"。

您可以使用 placement new 亲自查看。考虑以下代码:

#include <iostream>

struct Test
{
    int s;
    float m;
    Test(int a,float b) : s(a),m(b)
    { }
    Test()=default;
};

int main()
{
    char* buf = new char[sizeof(Test)];
    Test* t = new (buf) Test;

    std::cout << t->s << '\n';
    std::cout << t->m <<'\n';

    t->s = 42;
    t->m = 4.2;

    t->~Test();
    t = new (buf) Test;

    std::cout << t->s << '\n';
    std::cout << t->m <<'\n';
}

如果保证默认构造函数对非class类型的数据成员进行零初始化,则该程序的输出将是四个零。

但是,您可能会看到类似这样的内容:

0
0
42
4.2

这是 cpp.sh - http://cpp.sh/9fdj

上的代码