Подтвердить что ты не робот

Является ли новый int [10]() допустимым С++?

Пытаясь ответить на этот вопрос, я обнаружил, что код int* p = new int[10](); компилируется с компилятором VC9 и инициализирует целые числа до 0. Поэтому мои вопросы:

  • Прежде всего, это допустимый С++ или это расширение Microsoft?
  • Гарантируется ли инициализация всего элементы массива?
  • Кроме того, есть ли разница, если я do new int; или new int();? Есть ли последняя гарантия для инициализации переменная?
4b9b3361

Ответ 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 (я думаю), где компилятор сказал, что "этот член будет теперь инициализирован нулевым значением, это было не раньше".