Массивы переменной длины (VLA) в C и c++

Возможные Дубликаты:
изменяемый массив в области файла

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

AFIK с C99 можно объявить VLA в локальных областях:

int main(int argc, char **argv)
{
    // function 'main' scope
    int size = 100;
    int array[size];
    return 0;
}

но это запрещено в глобальных масштабах:

const int global_size = 100;
int global_array[global_size]; // forbidden in C99, allowed in C++

int main(int argc, char **argv)
{
    int local_size = 100;
    int local_array[local_size];
    return 0;
}

код выше объявляет VLA в C99, потому что const модификатор не создает значение времени компиляции. В C++ global_size является значением времени компиляции so,global_array не становится VLA.

что мне нужно знать: правильно ли мое рассуждение? Поведение, которое я описал правильно?

Я также хочу знать: почему VLA в глобальном масштабе не разрешены? запрещены как в C и C++? По какой причине поведение массивов в глобальной и локальной областях было различным?

5 ответов


Да, ваши рассуждения верны, именно так эти различные формы объявлений и определений массива рассматриваются C и c++.

как уже говорили другие, VLA с истинной переменной длиной (не -const) в глобальном масштабе трудно понять. Каким будет порядок оценки, e.g если выражение длины будет ссылаться на объект другой единицы компиляции? C++ не имеет VLA, но имеет динамическую инициализацию объектов в области файлов. И уже это дает вам довольно головную боль, Если вам нужно полагаться на порядок оценки.

это оставляет небольшой пробел для C относительно выражений длины, которые содержат a const квалифицированный объект, который не допускается. Это происходит из-за того, что такие объекты не считаются "целочисленными постоянными выражениями" стандартом C. Это, возможно, могло бы измениться в будущих версиях, но до сих пор комитет C не считал необходимым допускать такое: есть enum константы, которые играют их единственным ограничением является то, что они ограничены int В C, было бы неплохо также иметь их size_t.


C++ не поддерживает VLAs, точка. Причина, по которой второй фрагмент кода работает на C++, заключается в том, что const ключевое слово создает константу времени компиляции в C++: в C, это не так.

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


Я думаю, что основная причина-глобальная переменная имеет связь, ее размер должен быть известен во время компиляции. Если нет,то как можно связать программу?

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


есть разница между запретом и запретом. ;-)

функция VLA предназначена для использования пространства стека для локального массива, чтобы избежать использования malloc для распределения кучи. Это в основном оптимизация скорости.

теперь вы хотите использовать VLAs вне функций. Почему? Существует не так много, чтобы выиграть быстро во избежание одного вызова malloc во время запуска программы. И какое пространство стека мы должны использовать для переменных со статической жизнью время?


Итак, для глобальных VLA's одна из проблем (есть много вариантов ПО ТЕМЕ) Может быть показана здесь:

int size;
int a;
int v[size];
int b;

.... в другом файле:

extern int a;
extern int b;

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