Инициализация значений и типы не POD
Час назад я отправил ответ here, который, по моему мнению, был правильным. Однако мой ответ был отклонен Мартином B. Он сказал
Вам просто повезло и получают нули, потому что память, в которую я была помещена, оказалась нулевой инициализацией. Это не гарантируется стандартом.
Однако после прочтения Michael Burr ответьте здесь и попробуйте следующий пример кода
1)
#include <cassert>
struct B { ~B(); int m; };
int main()
{
B * b = new B();
assert(b->m == 0);
}
Я получил ошибку отладки на MSVС++ 2010.
У меня была аналогичная ошибка, когда я попробовал следующий код [My answer here] на MSVС++ 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, которая заставляла меня думать, что MSVС++ 2010 не поддерживает С++ 03. Я не уверен.
Согласно сообщению Майкла Берра [в С++ 03]
new B() - значение инициализирует B, который нуль инициализирует все поля, поскольку его по умолчанию ctor является компилятором, сгенерированным, в отличие от пользовательского.
В стандарте говорится
Чтобы инициализировать объект типа Tmeans:
- если T - тип класса (раздел 9) с объявленным пользователем конструктором (12.1), , то конструктор по умолчанию для T называется (и инициализация плохо сформирована, если Thas no доступный конструктор по умолчанию);
.....
, в противном случае объект инициализируется нулем
Из первой точки, если нет объявленного пользователем конструктора по умолчанию, будет вызываться компилятор, синтезированный по умолчанию конструктор, который будет zero initialize
всех полей (в соответствии с последней точкой).
Итак, где я ошибаюсь? Правильно ли моя интерпретация инициализации значений?
Ответы
Ответ 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
Ответ 2
Для людей, которые наткнулись на этот вопрос в 2015 году, как и я:
Все вышеперечисленные проблемы были исправлены в VS 2015. Инициализация значения теперь работает, как определено в стандарте.