Почему глобальный размер массива должен быть целочисленной константой? - PullRequest
8 голосов
/ 10 марта 2020

В C ++ я пытался объявить глобальный массив некоторого размера. Я получил ошибку:

привязка массива не является целочисленной константой до токена ']'

Но когда я объявил массив того же типа в main() функция работает нормально.

Почему здесь другое поведение?

int y=5;
int arr[y];         //When I comment this line it works fine

int main()
{
    int x=5;
    int arr2[x];        // This line doesn't show any error.
}

Редактировать: Многие полагают, что этот вопрос является дубликатом Получение ошибки ", привязка массива не является целочисленная константа перед ']' токеном ". Но этот вопрос не отвечает, почему существует другое поведение.

Ответы [ 4 ]

9 голосов
/ 10 марта 2020

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

Почему здесь другое поведение?

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

Если вы используете G CC, вы можете запросить его соответствие стандарту с помощью параметра командной строки -pedanti c. Это хорошая идея, чтобы быть в курсе проблем переносимости.

4 голосов
/ 10 марта 2020

Размер массива должен быть постоянным. Это можно исправить, объявив y как const.

const int y=5;
int arr[y]; 

Что касается того, почему это работало в main, g ++ допускает использование массива переменной длины в области видимости блока как расширения. Однако это не стандартный C ++.

0 голосов
/ 09 апреля 2020

Система типов C ++ обрабатывает эти C -подобные массивы так, как она определяет arr2 из вашего примера типа int[5]. Итак, да, количество элементов массива является частью типа!

Это накладывает некоторые ограничения на то, что вам разрешено использовать в определении C -подобных массивов. Т.е. это число должно иметь stati c хранилище , должно быть неизменным и должно быть доступно во время компиляции .

Так Возможно, вы захотите изменить свой код на что-то вроде следующего, что будет иметь еще один хороший ie. Он правильно инициализирует массив:

int arr2[] = {0, 0, 0, 0, 0};   
0 голосов
/ 10 марта 2020

Оба не должны использоваться, один работает, потому что (как сказал @eerorika) автоматические массивы c разрешены во время выполнения, но глобальные массивы должны иметь stati c хранилище.

Если вы Если вы хотите объявить массив с переменным размером (например, заданный std :: cin), вы должны сделать что-то вроде:

int x;
std::cin >> x;
const int n = x;
float arr[n];

Но вы не сможете установить его так, чтобы он содержал только нули с float arr[n] = {0} (если вам нужно добавить значение в массив, не будучи уверенным, что вы его установили), вам нужно будет использовать al oop вот так

for(int i = 0; i < n; i++)
{
    arr[i] = 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...