Почему мой код на C ++, который объявляет (локальный) массив int без каких-либо действий по инициализации нулями? - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть два кода C ++, в которых один имеет глобальный массив int, а другой - локальный массив, длина которого определяется пользовательским вводом (так во время выполнения). Оба массива не инициализируются явно.

#include <iostream>
using namespace std;
int M = 1000;
int a[M];
int main() {
  for(int i = 0; i < M; i++)
    cout << a[i];
  cout << endl; 
}
#include <iostream>
using namespace std;
int main() {
  int M;
  cin >> M;
  int a[M];
  for(int i = 0; i < M; i++)
    cout << a[i];
  cout << endl; 
}

Я заметил, что глобальный массив заполнен нулями, в то время как локальный массив (длина которого определяется во время выполнения) не заполнен нулями и вместо этого заполнен со случайными числами (но одинаковыми за раз). Я использовал компилятор g ++.

Что это за поведение? Стандарт C ++ определяет это поведение?

Ответы [ 2 ]

3 голосов
/ 17 февраля 2020

Что это за поведение?

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

Поведение для всей другой продолжительности хранения таково, что никакой дополнительной инициализации нуля нет.

Стандарт C ++ определяет это поведение?

Да, нулевая инициализация состояния c объектов определено в стандарте. Поведение чтения неопределенных значений определено как неопределенное.

Обе программы плохо сформированы, поскольку размер массива (не Dynami c) должен быть постоянной времени компиляции, а M - нет.

0 голосов
/ 17 февраля 2020

Из стандарта C ++ 17 (инициализаторы 11.6)

12 Если для объекта не указан инициализатор, объект инициализируется по умолчанию. Когда получается хранилище для объекта с автоматическим c или динамическим c сроком хранения, объект имеет неопределенное значение, и если для объекта не выполняется инициализация, этот объект сохраняет неопределенное значение до тех пор, пока это значение не будет заменено (8.18 ). [Примечание: объекты со значением c или продолжительностью хранения потока инициализируются нулями, см. 6.6.2. - конец примечания]

Таким образом, массив, объявленный в глобальном пространстве имен, имеет стати c длительность хранения и инициализируется нулями

, в то время как массив, объявленный в main, имеет автомат c длительность хранения и имеет неопределенные значения своих элементов.

Обратите внимание, что массивы переменной длины не являются стандартной функцией C ++.

int M = 1000;
int a[M];

или

cin >> M;
int a[M];

То есть обе программы не соответствуют стандарту.

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

Некоторые компиляторы могут поддерживать их как собственные языковые расширения.

...