Инициализация по умолчанию типов POD в переполнении стека

я знаю, некоторые POD переменные инициализируются по умолчанию, а другие нет. (Типы POD включают int, float, указатели, объединения, массивы типов POD, структуры типов POD и т. д.)

Как область и класс хранения влияют на инициализацию по умолчанию типов POD?

В частности, что из следующего будет неявно инициализировано:

  • Локальные переменные с автоматическим хранением
  • Статические локальные переменные
  • Статические глобальные переменные
  • Внешние переменные
  • Переменные, выделенные с new
  • POD-члены класса (без явной инициализации в конструкторе)

Я знаю, что существуют некоторые вопросы, касающиеся некоторых из этих ситуаций, но они не являются исчерпывающими (они касаются только конкретных ситуаций).

12

Решение

Локальные переменные с автоматической продолжительностью хранения не инициализируются автоматически. Поскольку использование неинициализированных переменных производит неопределенное поведение, Хорошей практикой является явная инициализация переменных, даже если они избыточны.

О типах POD, которые инициализируются нулями, стандарт C ++ 03 3.6.2 Инициализация нелокальных объектов состояния:

§ 1 Объекты с статическая продолжительность хранения (3.7.1) должен быть нулевой инициализируется (8.5) до любой другой инициализации. Нулевая инициализация и инициализация с постоянным выражением вместе называются статической инициализацией; все остальные инициализации — это динамическая инициализация. Объекты типов POD (3.9) со статической продолжительностью хранения, инициализированные с помощью константных выражений (5.19), должны быть инициализированы перед любой динамической инициализацией.

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

POD-члены класса (без явной инициализации в конструкторе)

Эта ситуация описана в 12.6.2 Инициализация баз и членов, который заявляет (выбранные части):

Если данный нестатический элемент данных или базовый класс не именуются с помощью mem-initializer-id (включая случай, когда нет mem-initializer-list, потому что конструктор не имеет ctor-initializer), тогда:

— Если субъект является нестатический элемент данных…, и класс сущности это не POD класс, сущность по умолчанию инициализируется (8,5) …

В противном случае сущность не инициализируется

После завершения вызова конструктора для класса X, если член X не указан ни в mem-инициализаторах конструктора, ни в инициализированных по умолчанию, ни в инициализированных значениях, ни в качестве значения во время выполнения тела конструктора, член имеет неопределенную ценность.

Пример:

class C
{
public:
C(int x, int z) : x(x), z(z) { }
int x, y, z;
};

int main(void)
{
C* c = new C(1,3);
std::cout << c->y; // value of y is undetermined !!!
}
14

Другие решения

Если мы говорим только о POD, то только локальная и глобальная статика а также внешние переменные потому что они должны быть определены где-то.

POD, выделенные с new также инициализируются иногда — если вы делаете инициализацию явной:

int* x = new int();

создаст int инициализирован в 0 с x указывая на это, тогда как

int* x = new int;

буду иметь x указывают на неинициализированный int,

Иногда — члены класса POD — они могут быть инициализированы явно (без использования конструктора):

struct X
{
int x;
};

X x;        //x.x is not initialized
X y = X();  //y.x is 0
7

По вопросам рекламы [email protected]