Вопрос

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

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

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

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

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

Я тоже пытался найти что-то в стандарте, но пока безуспешно.

Кто-нибудь знает авторитетный источник, подтверждающий вышеизложенное?

Это было полезно?

Решение

ISO C++03 настолько авторитетен, насколько это возможно:

POD-структура — это агрегатный класс, который не имеет нестатических элементов данных типа, отличного от POD-struct, не-POD-union (или массива таких типов) или ссылки, а также не имеет определяемого пользователем оператора присваивания копирования и не имеет определяемый пользователем деструктор.Аналогичным образом, POD-объединение — это агрегатное объединение, которое не имеет нестатических элементов данных типа не-POD-struct, не-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, базовый тип класса должен иметь объявленный пользователем конструктор по умолчанию.В противном случае, если для нестатического объекта не указан инициализатор, объект и его подобъекты, если таковые имеются, имеют неопределенное начальное значение);если объект или любой из его подобъектов имеют константный тип, программа имеет неверный формат.

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

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

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

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

Другие советы

В стандарте C ++ написано в 8.5.9:

  

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

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

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

  • Массивы и структуры, объявленные как static инициализируются нулями.
  • Локальные массивы и структуры встроенных типов (то есть типы, не имеющие конструкторов), не инициализируются.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top