【问题标题】:Value initialization and Non POD types值初始化和非 POD 类型
【发布时间】:2011-04-25 06:48:19
【问题描述】:

一个小时前,我发布了一个答案here,据我说是正确的。但是我的回答被Martin B 否决了。他说

你很幸运并且得到了零,因为我所在的内存恰好是零初始化的。标准不保证这一点。

但是在阅读了 Michael Burr 的回答 here 并尝试了以下示例代码之后

1)

#include <cassert>

struct B { ~B(); int m; };

int main()
{
   B * b = new B();
   assert(b->m == 0);
}

我在 MSVC++ 2010 上遇到调试错误。

当我在 MSVC++2010 上尝试以下代码 [My answer here] 时遇到类似错误

2)

#include <cassert>
struct Struct {
    std::string String;
    int Int;
    bool k;
    // add add add
};

struct InStruct : Struct
{
   InStruct() : Struct() {}
};

int main()
{
   InStruct i;
   assert(i.k == 0);
}

(1)(2) 在 gcc/Clang 上都没有给出任何此类错误,这让我想到 MSVC++2010 是否不支持 C++03。我不确定。

根据 Michael Burr 的帖子 [in C++03]

new B() - 值初始化 B,它零初始化所有字段,因为它的默认 ctor 是编译器生成的,而不是用户定义的。

标准说

对 Tmeans 类型的对象进行值初始化:

——如果 T 是具有用户声明的构造函数 (12.1) 的类类型(第 9 条),则调用 T 的默认构造函数(如果没有,则初始化是非良构的可访问的默认构造函数);

.....

否则,对象被零初始化

从第一点开始,如果没有用户声明的默认构造函数,编译器合成的默认构造函数将被调用,这将zero initialize所有字段(根据最后一点)。

那么我哪里错了?我对值初始化的解释正确吗?

【问题讨论】:

标签: c++ visual-c++ initialization value-initialization


【解决方案1】:

Visual Studio 在所有当前版本(2005、2008、2010)中都存在已知错误,其中它无法正确地为没有用户声明的构造函数的非 POD 类型实现值初始化。

根据语言规则,你们中的任何一个断言都不应该触发,但确实会出现编译器问题。这些是一些错误报告,请注意它们都已关闭或解决为“不会修复”。

http://connect.microsoft.com/VisualStudio/feedback/details/564268/c-value-initialization

http://connect.microsoft.com/VisualStudio/feedback/details/484295/vc-does-not-value-initialize-members-of-derived-classes-without-user-declared-constructor

http://connect.microsoft.com/VisualStudio/feedback/details/100744/value-initialization-in-new-expression

【讨论】:

  • +1 和...哇,我仔细阅读了那些反馈项目,我很震惊。在 OP 的第一个 sn-p 中,只有在有用户提供的析构函数时才会出现问题。如果没有用户提供的析构函数,则变量已正确初始化。因此,这为大量代码缺陷留出了空间,所有理智的 Visual C++ 开发人员都应该更好地意识到这个问题。
  • @Naveenn:现有代码库。我认为他们至少应该在每次他们没有正确实施事情时发出警告(比如他们对typename关键字的松懈)
  • @sharptooth:“所有理智的 Visual C++ 开发人员”,我不知道如何在使用 Visual C++ 时保持理智。我发现保持理智的唯一方法就是停止使用它:x
  • @Matthieu M. 所以你切换到..?
  • @mlvljr:由 clang over mingw 支持的代码块。下一步是在 VM 中运行完整的 Linux 以进行编译。当然,我只是“为了好玩”而玩 Visual Studio,而不必提供 Windows 软件,这很有帮助;)
【解决方案2】:

对于像我这样在 2015 年偶然发现这个问题的人:

以上所有问题都已在 VS 2015 中修复。值初始化现在可以按照标准中的定义进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多