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

Основываясь ниже, я прав?

  • Ссылка global_A инициализируется нулем.
  • global_int = 0
  • local_A ссылка null
  • local_int неинициализирован
  • Оба global_A.x и local_A.x не инициализируются.

Спасибо за любую помощь.


A global_A;
int global_int;

class A {
  public : int x;
}

int main()
{
  int local_int;
  A local_A;
}

Ответ 1

Настроить ответ Андрея.

$3.6.2- "Объекты со статической продолжительностью хранения (3.7.1) должны быть инициализированы нулями (8.5) до начала любой другой инициализации". В OP "global_A" и "global_int" имеют статическую продолжительность хранения. "local_int" и "local_A" не имеют связей, поскольку это локальные объекты.

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

- если T - скалярный тип (3.9), то объект установлен в значение 0 (ноль) преобразован в T;

- если T - тип неединичного класса, каждый нестатический элемент данных и каждый подобъект базового класса zeroinitialized;

- если T - тип объединения, объекты первый элемент данных89) нулевой инициализируется;

- если T - тип массива, каждый элемент инициализируется нулем;

- если T является ссылочным типом, no выполняется инициализация.

$6.7.4/4- "Нулевая инициализация (8.5) всех локальных объектов со статической продолжительностью хранения (3.7.1) выполняется до любой другой инициализации. Локальный объект типа POD (3.9) со статическим длительность хранения, инициализированная константными выражениями, инициализируется до того, как будет введен ее блок. Реализация разрешена для выполнения ранняя инициализация других локальных объектов со статической продолжительностью хранения при тех же условиях, что реализации разрешено статически инициализировать объект со статической продолжительностью хранения в области пространства имен (3.6.2). В противном случае такой объект инициализируется, когда первый контроль проходит через его объявление; такой объект считается инициализированным после завершения его инициализации. Если инициализация завершается путем исключения исключения, инициализация не завершена, поэтому она будет снова проверена, когда следующий элемент управления войдет в объявление. Если управление повторно вводит объявление (рекурсивно), пока объект инициализируется, поведение undefined. "

ИЗМЕНИТЬ 2:

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

В общем, вы хотите прочитать эти разделы вместе с 8,5 долларами для хорошего удержания этого аспекта.

Ответ 2

В вашем коде нет ссылок, поэтому любые ваши точки, которые упоминают "ссылки", не имеют смысла.

В вашем примере оба глобальных объекта - global_int и global_A - инициализируются нулями. Оба локальных объекта - local_int и local_A - содержат неопределенные значения, что означает, что local_int и local_A.x не инициализируются.

P.S. Конечно, как уже отмечалось, ваш код не компилируется. Вы не можете объявить A объекты перед объявлением class A (и после определения класса отсутствует ;).

Ответ 3

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

Типы уровня языка (например, указатели, "int", "float", "bool" и т.д.) "конструктор по умолчанию" абсолютно ничего не делает, он просто оставляет память так, как она объявляется (глобальные/статические переменные являются особыми случаями, см. chubsdad answer для получения дополнительной информации о специфике). Это означает, что они могут быть почти что угодно, потому что вы, как правило, не можете быть уверены, что было в этой памяти ранее или даже там, откуда появилась память (кроме случая с оператором "новый номер" ).

Созданный вами класс не имеет конструкторов, поэтому компилятор будет генерировать для вас конструктор по умолчанию, который просто вызывает конструктор каждого из его членов/переменных. Если вы включили информацию, представленную в предыдущем абзаце, вы увидите, что переменная "x" будет иметь свой конструктор по умолчанию, который ничего не делает и, следовательно, не инициализируется никаким значением.

Как говорили другие, в вашем коде или указателях нет ссылок, поэтому термин "NULL" здесь недействителен. NULL обычно ссылается на указатель, который, как и другие типы языкового уровня, не получает ничего, пока вы не присвоите ему значение (если, конечно, его глобальная/статическая переменная).

Ответ 4

Просто для полноты, если у вас есть ссылки:

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

Ответ 5

global_A и local_A не являются ссылками; они являются объектами и создаются с использованием их конструкторов по умолчанию. Конструктор по умолчанию не указан, поэтому он будет сгенерирован, что ничего не сделает, поэтому переменная-член останется неинициализированной.

Ответ 6

A global_A;

Это instace, а не указатель, ваша программа вызовет конструктор перед входом в main.

Чтобы получить указатель на экземпляр, а не экземпляр, который вы должны написать:

A* global_A;

global_int инициализируется на 0, так как все глобальные переменные инициализируются по умолчанию.

Переменная A local_A будет инициализироваться каждый раз, когда ваша программа входит в функцию, в которой объявляется вызовом его конструктору.

Как и раньше, если вам нужен указатель на A, вам нужно написать A * local_A, но на этот раз вы должны инициализировать его в NULL самостоятельно.

A *local_A = NULL;

Параметр local_int не будет инициализирован, поскольку он является примитивным типом.

Если local_A.x инициализируется, зависит от конструктора A, конструктор по умолчанию не будет инициализировать local_A.x. Если x, где экземпляр класса, создающий экземпляр A, инициализирует x конструктором своего класса.

Ответ 7

Все они требуют инициализации. Компилятор даст вам предупреждение об этом.

Ответ 8

Этот код не будет компилироваться, если вы не перешлите объявление A.

Ссылка global_A инициализируется нулем - Нет, она будет ссылаться на объект A. global_int - 0 - Подумайте, нужно проверить. local_A имеет значение null - Нет, то же, что и для global_A. local_int не инициализирован. Да, он получит некоторую стоимость мусора. И global_A.x, и local_A.x не инициализированы - Да.

Вы всегда можете отлаживать и видеть сами.

Ответ 9

Ну, ребята, я больше смущен, так как вижу ответы отсюда. В любом случае я сделал тест, как показано ниже:

1 #include

  2 using namespace std;
  3 
  4 class A {
  5 
  6 public :
  7         A() : x(9) {};
  8         int x;
  9 
 10 };
 11 
 12 A global_a;
 13 int global_b;
 14 
 15 int main() {
 16 
 17         A local_a;
 18         int local_b;
 19         cout << "global_a.x = " << global_a.x << '\n';
 20         cout << "local_a.x = " << local_a.x << '\n';
 21 
 22         cout << "global_b = " << global_b << '\n';
 23         cout << "local_b = " << local_b << '\n';
 24 
 25 }

Результаты с использованием моего компилятора g++ на ubuntu linux:

global_a.x = 9

local_a.x = 9

global_b = 0

local_b = 0

Я думаю, что local_b должен быть undefined, но каким-то образом компилятор его инициализировал по умолчанию. Однако local_a.. я не уверен, что это должно быть инициализировано по умолчанию. Из теста здесь.. local_a кажется инициализированным. Не уверен, что это соответствует стандартной спецификации С++ (например, С++ PRimer 4th edition говорит, что конструктор по умолчанию используется независимо от того, где объявлена ​​переменная класса - означает ли это, что переменная типа класса инициализируется, является ли она глобальной или локальной?).

Что бы это ни было... это одна большая путаница. Может быть, я должен прекратить обучение С++. Java намного более прямолинейна. Hell yeahhh!!

Ответ 10

Ссылка global_A инициализируется нуль.

Нет, его действительный объект (построенный на основе конструктора по умолчанию, которого у вас нет в коде, но компилятор добавляет это)

global_int = 0

да

local_A ссылка имеет значение null

нет, по той же причине, что и для глобальных

local_int неинициализирован

нет, его инициализируется 0

Как global_A.x, так и local_A.x неинициализированным.

no оба инициализируются до 0