gpt4 book ai didi

c++ - 为什么将值初始化指定为不调用平凡的默认构造函数?

转载 作者:行者123 更新时间:2023-12-04 11:15:02 25 4
gpt4 key购买 nike

To value-initialize an object of type T means:

...

— if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;


我理解这里的意图:如果用户没有为 T 声明默认构造函数,或者在第一次声明时明确默认它,那么值初始化的零初始化传递将确保对象的某些直接成员(例如基本类型的成员)不会留下不确定的值。
我不明白的是为什么第二遍被指定为“检查了默认初始化的语义约束,如果 T 具有非平凡的默认构造函数,则对象被默认初始化”。对我来说,这与只是说“对象是默认初始化的”相同(无论默认构造函数是否微不足道)。如果构造函数实际上是微不足道的,那么调用它应该与不调用它相同。标准不需要告诉编译器不要生成调用,因为在 as-if 规则下允许这样的优化,任何好的编译器都会这样做。
我错过了什么吗?在值初始化上下文中,调用一个平凡的默认构造函数与不调用它有什么不同吗?

最佳答案

我一直无法找到对我的问题的权威答案。但是,查看 C++03 标准,我有一个粗略的想法。 C++03 定义了类型的值初始化 T如下:

  • T是具有用户声明构造函数的类类型,然后调用默认构造函数;
  • T是一个没有用户声明的构造函数的非 union 类类型[这意味着编译器隐式声明了一个默认构造函数],那么每个基类子对象和成员子对象都是值初始化的;
  • [...]

  • 第二个要点确保标量类型的直接子对象是零初始化的,因此比简单地调用隐式默认构造函数“更强”。这是值初始化背后的意图。
    所以 C++03 中的措辞是有道理的,自然会导致以下结果:当默认构造函数是平凡的时,实际上不会发生函数调用。
    在 C++11 中,零初始化的定义已更改,以便它还将填充位初始化为零 ( CWG 694 )。我的猜测是,围绕值初始化的措辞已更改,以确保在普通默认构造函数的情况下,值初始化也能保证将填充位清零。所以在 C++11 中,当 T (没有用户提供的默认构造函数的类型)是值初始化的,所发生的事情比仅仅值初始化 T 的所有直接子对象更强。 .相反,整个 T对象首先被零初始化(以确保填充被清零),然后调用默认构造函数。
    但同样,我们的问题是为什么在默认构造函数微不足道的情况下会出现异常。 paper这使得措辞改变并没有解释为什么要加入这个异常,但我们现在可以看到它保留了 C++03 的行为,其中根本没有调用一个简单的默认构造函数。我的猜测是作者有意加入措辞以保留这种行为。正如我在问题中所说,调用一个简单的默认构造函数不会影响性能,因为编译器会优化调用。但也许作者担心如果 C++11 指定了一个调用(对一个简单的默认构造函数)而 C++03 没有指定,那么某些东西(他们可能无法预料)会中断。保持没有这样的调用比担心这个更容易。
    尽管如此,我们还是应该观察到 C++11 的行为与 C++03 的行为以及填充的零初始化并不完全相同。假设我们有一个这样的类型:
    struct T {
    struct U { U() {} } u;
    int x;
    };
    在 C++03 中, T 的值初始化意味着 U::U被调用然后 x是零初始化的。在 C++11 中,表示整个 T对象被零初始化,然后 T::T被调用,后者又调用 U::U .所以与 C++03 相比,C++11 在这里多了一个函数调用。因此,尽管作者尽了最大努力,但行为并不相同。据我所知,这种差异不会破坏任何代码。
    在 C++11 到 C++17 中,调用一个平凡的默认构造函数和不调用它是有区别的。如果你调用它,它会导致封闭表达式不能成为一个常量表达式(见 here)。这是我所知道的唯一区别。也许 N2762 的作者打算编译这样的代码,这就是为什么他们说不调用平凡的构造函数。但是,我发现这不太可能,因为它是一种“边缘情况”。

    关于c++ - 为什么将值初始化指定为不调用平凡的默认构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63478034/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com