Ответ 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