18

一小时前,我在这里发布了一个答案,据我所知是正确的。然而,我的回答被Martin B否决了。他说

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

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

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);
}

在 gcc/Clang 上既没有(1)也没有(2)给出任何这样的错误,这让我想到 MSVC++2010 是否不支持 C++03。我不知道。

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

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

标准说

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

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

......

否则,对象被零初始化

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

那么我错在哪里?我对值初始化的解释是否正确?

4

2 回答 2

34

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

于 2010-10-14T08:56:21.860 回答
8

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

所有上述问题已在 VS 2015 中修复。值初始化现在按照标准中的定义工作。

于 2015-12-16T11:31:14.797 回答