Инициализация массива - программирование

Инициализация массива

Я вполне уверен, что массивы встроенных типов унифицированы, тогда как массивы UDT инициализируются по умолчанию.

int foo[5]; // will contain junk
Foo foo[5]; // will contain 5 Foo objects that are default initialized

Это происходит независимо от того, выделен ли массив в стеке или куче.

Однако мне трудно найти авторитетный источник. Бьярне утверждает, что:

"Члены массивов и структур по умолчанию инициализируются или не зависят от того, является ли массив или структура статичным", что на самом деле не говорит мне слишком много.

Я также пытался найти что-то в стандарте, но до сих пор ничего не получилось.

Кто-нибудь знает об авторитетном источнике, чтобы подтвердить это?

4b9b3361

Ответ 1

ISO С++ 03 примерно такой же авторитетный, как и он:

A POD-struct - это совокупный класс, который не имеет нестатических членов данных типа non-POD-struct, non-POD-union (или массив таких типов) или ссылки и не имеет пользовательского назначения копирования оператора и без определяемого пользователем деструктора. Аналогичным образом, POD-union представляет собой совокупный союз, который не имеет нестатических членов данных типа non-POD-struct, non-POD-union (или массив таких типов) или ссылки и не имеет определенного пользователем оператора назначения копирования и не определяемый пользователем деструктор. Класс POD - это класс, который является либо POD-структурой, либо POD-соединением.

Арифметические типы (3.9.1), типы перечислений, типы указателей и указатели на типы членов (3.9.2), а также cv-квалификационные версии этих типов (3.9.3), все вместе называются скалярными типами. Скалярные типы, типы POD-структуры, типы POD-соединения (раздел 9), массивы таких типов и cv-квалификационные версии этих типов (3.9.3) совместно называются типами POD.

Для нулевой инициализации объекта типа T означает:

  • если T - скалярный тип (3.9), объект устанавливается в значение 0 (ноль), преобразованное в T;
  • если T - тип неединичного класса, каждый нестатический член данных и каждый базовый класс подобъект инициализирован нулем;
  • если T - тип объединения, объекты, сначала названные членами данных, инициализируются нулем;
  • если T - тип массива, каждый элемент инициализируется нулем;
  • если T является ссылочным типом, инициализация не выполняется.

Для инициализации объекта типа T по умолчанию:

  • если T - тип класса не POD (раздел 9), вызывается конструктор по умолчанию для T (и инициализация плохо сформирована, если T не имеет доступного конструктора по умолчанию);
  • если T - тип массива, каждый элемент инициализируется по умолчанию;
  • в противном случае объект инициализируется нулем.

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

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

Каждый объект статической продолжительности хранения должен быть инициализирован нулем при запуске программы до начала любой другой инициализации. [Примечание: в некоторых случаях дополнительная инициализация выполняется позже.]

Объект, инициализатор которого представляет собой пустой набор скобок, т.е.(), должен инициализироваться значением.

Если для объекта не задан инициализатор, а объект имеет (возможно, cv-квалифицированный) тип класса не-POD (или его массив), объект должен быть инициализирован по умолчанию; если объект имеет тип const-type, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию. В противном случае, если для нестатического объекта не указан инициализатор, объект и его подобъекты, если они есть, имеют неопределенное начальное значение); если объект или какой-либо из его подобъектов имеют тип, соответствующий const, программа плохо сформирована.

В вашем примере int определенно является типом POD (это арифметический тип), и поэтому локальное или поле типа int, при отсутствии инициализатора, будет иметь неопределенное значение. Для Foo это зависит от того, как это определено - грубо говоря, если у него нет конструктора, и все его члены имеют типы POD, то он сам является POD-типом, и никакая инициализация не происходит. В противном случае вызывается конструктор по умолчанию. Даже тогда это не означает, что члены инициализируются - правила являются рекурсивными, поэтому члены POD типа не-POD не будут инициализированы, если конструктор этого типа не делает это (в его списке инициализаторов).

Статические переменные и поля во всех случаях будут инициализированы нулем. Обратите внимание, что это относится и к не-PODs - это означает, что статическая переменная типа класса гарантирована, что все поля будут рекурсивно настроены на (T)0 еще до запуска его конструктора.

Удобный трюк по умолчанию - инициализировать любой совокупный тип POD - использовать {} в инициализаторе - обратите внимание, что он работает как с структурами, так и с массивами:

char s[10] = {}; // all elements default-initialized
Foo foo = {};    // all fields recursively default-initialized

Ответ 2

"Члены массивов и структур по умолчанию инициализируются или не зависят от того, является ли массив или структура статичным"

Это авторитетно, хотя это может быть яснее:

  • Массивы и структуры, объявленные как static, инициализируются нулями.
  • Локальные массивы и структуры встроенных типов (т.е. типы, не имеющие конструкторов) не инициализируются.

Ответ 3

Он говорит в стандарте С++, в 8.5.9:

Если для объект, и объект имеет (возможно, cv-квалифицированный) тип класса не-POD (или массив), объект должен быть по умолчанию инициализируется; если объект типа const, тип базового класса должен иметь объявленный пользователем конструктор по умолчанию. В противном случае, если инициализатор не установлен для нестатического объекта, объект и его подобъекты, если они есть, имеют неопределенное начальное значение.