К чему может привести, или вообще ни к чему не приведёт, задание размера статического массива значением, которое станет известно лишь на этапе выполнения программы?
Знаю лишь то, что это не по стандарту языка C++
, в C
это вполне себе законно.
Примером будет выступать вот такой код:
int main()
{
int n;
std::cin >> n;
T arr[n];
/*код, включающий в себя работу с массивом arr*/
return 0;
}
В языке С++ такие массивы не поддерживаются
В типичной традиционной реализации 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.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть задание найти значение в массиве и вывести егоДля этого я использую бинарный поиск, но не могу понять почему выводит ошибку
Задача в следующем, мне нужно написать прогу, которая отправляла бы на указанные адреса почт моих контрагентов письма с вложениями (не спам...
извиняюсь за нубский вопрос: при обьявлении и инициализации переменных - как происходит восприятие указателем или онлайн-компилятором их адреса?...