Является ли новый int [10]() допустимым С++?
Пытаясь ответить на этот вопрос, я обнаружил, что код int* p = new int[10]();
компилируется с компилятором VC9 и инициализирует целые числа до 0. Поэтому мои вопросы:
- Прежде всего, это допустимый С++ или
это расширение Microsoft?
- Гарантируется ли инициализация всего
элементы массива?
- Кроме того, есть ли разница, если я
do
new int;
или new int();
? Есть ли
последняя гарантия для инициализации
переменная?
Ответы
Ответ 1
Прежде всего, это допустимый С++ или это расширение для Microsoft?
Он действителен в С++, соответствующая часть стандарта - 5.3.4, причем первый абзац содержит грамматику
Гарантируется ли инициализация всех элементов массива?
Да. В пункте 5.3.4/15 говорится, что
Новое выражение, создающее объект типа T, инициализирует этот объект следующим образом:
...
- Если новый-инициализатор имеет форму(), элемент инициализируется значением (8.5)
где значение, инициализированное для POD, означает инициализацию нуля.
Кроме того, есть ли разница, если я делаю новый int; или новый int();? Предоставляет ли последняя возможность инициализировать переменную?
Да, они разные. Согласно приведенной выше цитате new int()
будет нулевой инициализировать целое число. В предыдущем блоке того же абзаца:
Если новый инициализатор опущен:
-
Если T является (возможно, cv-квалифицированным) классом типа не-POD (или его массивом), объект инициализируется по умолчанию (8.5). Если T - это тип, специфичный для const, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию.
-
В противном случае созданный объект имеет неопределенное значение. Если T - это тип, специфичный для const, или (возможно, cv-квалифицированный) тип класса POD (или его массив), содержащий (прямо или косвенно) член типа const, программа плохо сформирована;
поэтому new int
не будет инициализировать память.
Ответ 2
Из стандарта.
"Для инициализации объекта типа T по умолчанию: - если T - тип класса не-POD
[case like vector], вызывается конструктор по умолчанию для T. "
Обозначение конструктора T()
используется для выражения значения по умолчанию для типа T и что это значение равно нулю для встроенных типов и конструктор по умолчанию для пользовательских типов. Конструкция POD()
производит инициализацию значения и согласно stdandard, что приводит к тому, что все члены и дочерние элементы либо по умолчанию сконструированы, либо инициализированы нулями.
Вот почему ваше выражение является законным, но оно ноль инициализируется в соответствии со стандартом; нуждается в детальном поиске IMHO.
НО, я не смог найти в стандарте, где он определяет значение конструкции по умолчанию для встроенных типов.
EDIT: -
struct S { int x; };
void f () {
S s1; // s1.x is uninitialized here
S s2 = S(); // s2.x is zero here
}
Я думаю, что мы часто составляем собственную интерпретацию того, что используется по умолчанию для встроенных типов; потому что стандарт С++ не определяет его (по крайней мере, я не мог его найти), и я помню, что Stroustrup или Josuttis говорят, что это означает T()
, который описывается как инициализация значения: " нуль преобразован в тип T" для встроенных типов.
Так как int*
является встроенным типом, он инициализируется нулем.
Но я действительно не уверен.
Ответ 3
-
Это действительный С++ в соответствии с пунктом 5.3.4/1, который трудно выразить здесь из-за специального форматирования.
-
В соответствии с 5.3.4/15 элемент инициализируется значением, если используется форма(), см. параграф 8.5, но короткий ответ - да.
-
Да, в первом случае переменная не инициализируется значением и может быть чем угодно, во втором случае она инициализируется и будет равна нулю.
Ответ 4
Если я могу немного предсказать (я уверен, что меня исправит, если я ошибаюсь):
Последняя() инициализирует значение (как она называется в стандартном стандарте), что делает целое число в этом случае равным 0.
Это довольно новое дополнение к стандарту (С++ 03?), поэтому более старые компиляторы могут его не поддерживать, и оставьте его uniintialized.
Я помню, что получал много предупреждений w.r.t при переходе с MSVS 2003 на 2005 (я думаю), где компилятор сказал, что "этот член будет теперь инициализирован нулевым значением, это было не раньше".