Задание размера статического массива run-time значением

276
03 октября 2021, 13:30

К чему может привести, или вообще ни к чему не приведёт, задание размера статического массива значением, которое станет известно лишь на этапе выполнения программы?

Знаю лишь то, что это не по стандарту языка C++, в C это вполне себе законно.

Примером будет выступать вот такой код:

int main()
{
    int n;
    std::cin >> n;
    T arr[n];

    /*код, включающий в себя работу с массивом arr*/
    return 0;
}
Answer 1

В языке С++ такие массивы не поддерживаются

В типичной традиционной реализации VLA в языке C определение локального VLA

T arr[n];

будет втихаря заменено компилятором на два определения локальных переменных

size_t __size_arr;
T *arr;

Размер массива будет сохранен во внутренней переменной __size_arr

size_t __size_arr = n;

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

А память для самого массива будет выделена на вершине стека при помощи некоей внутренней платформенно-зависимой функциональности вроде alloca

T *arr = alloca(__size_arr * sizeof(T));

Также, в точке(-ах) выхода из блока, содержащего определение такого массива (таких массивов), компилятор сгенерирует код, возвращающий вершину стека в то положение, в котором она находилась при входе в этот блок, т.е. фактически освобождающий весь стек, выделенный для VLA в этом блоке.

Вычисление размера такого массива через sizeof arr будет порождать выражение вида

__size_arr * sizeof(T)

значение которого будет вычисляться во время выполнения. Если аргумент такого sizeof имеет побочные эффекты, то они возымеют место во время выполнения

unsigned n = 42;
unsigned a[n];
unsigned s = sizeof(*(printf("Hello World\n"), &a));
// Напечатает "Hello World"

Также, по понятным причинам, компилятор не позволит вам передавать управление (goto или switch) в области видимости таких массивов через объявления таких массивов и объявления соответствующих типов

goto skip; // Ошибка: нелегальный `goto`
unsigned n = 42;
unsigned a[n];
skip:;

(Подробнее см. здесь: Как работает VLA?)

Также, язык накладывает определенные ограничения на использование стандартных функций setjmp/longjmp в присутствии VLA.

READ ALSO
Бинарный поиск ошибка чтения

Бинарный поиск ошибка чтения

Есть задание найти значение в массиве и вывести егоДля этого я использую бинарный поиск, но не могу понять почему выводит ошибку

157
Отправить письмо

Отправить письмо

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

91
адресная арифметика с++ и онлайн компиляторы

адресная арифметика с++ и онлайн компиляторы

извиняюсь за нубский вопрос: при обьявлении и инициализации переменных - как происходит восприятие указателем или онлайн-компилятором их адреса?...

80
C++, вопрос про атомарность

C++, вопрос про атомарность

Я не могу найти ответы на следующие вопросы:

114