Инициализация значения и не POD типы - PullRequest
17 голосов
/ 14 октября 2010

Час назад я разместил ответ здесь , который, по моему мнению, был правильным.Однако мой ответ был отклонен Martin B .Он сказал

Вам просто повезло, и вы получаете нули, потому что память, в которой я находился, была инициализирована нулями.Это не гарантируется стандартом.

Однако, прочитав ответ Майкла Берра здесь и попробовав следующий пример кода

1)

#include <cassert>

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

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

Я получил ошибку отладки в MSVC ++ 2010.

Я получил похожую ошибку, когда попробовал следующий код [Мой ответ здесь ] в MSVC ++ 2010

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.Я не уверен.

Согласно сообщению Майкла Барра [в C ++ 03]

new B () - значение инициализирует B, которое инициализирует нулями все поляпоскольку его ctor по умолчанию генерируется компилятором , а не определенным пользователем.

Стандарт говорит:

Для инициализации значения объекта типа Tmeans:

- если T является типом класса (раздел 9) с объявленным пользователем конструктором (12.1), , тогда конструктор по умолчанию для T называется (и инициализация некорректна, если Thas noдоступный конструктор по умолчанию);

.....

в противном случае объект инициализируется нулями

С первой точки, еслине существует объявленного пользователем конструктора по умолчанию, будет вызван синтезированный компилятором конструктор по умолчанию, который будет zero initialize всеми полями (в соответствии с последней точкой).

Так в чем же я не прав?Правильна ли моя интерпретация инициализации значения?

Ответы [ 2 ]

33 голосов
/ 14 октября 2010

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

6 голосов
/ 16 декабря 2015

Для людей, которые сталкивались с этим вопросом в 2015 году, таких как я:

Все вышеперечисленные проблемы были исправлены в VS 2015. Инициализация значения теперь работает, как определено в стандарте.

...