Создание массива в функции на стеке с разным размером

Рейтинг: -1Ответов: 1Опубликовано: 29.03.2023
void foo(int b)
{
  static int a = 10;
  a += b; // or a = b
  int mass[a];
  for (int i = 0; i < a; i++) mass[i] = i;
  for (int i = 0; i < a; i++) std::cout << mass[i] << std::endl;
  std::cout << "foo" << std::endl;
}

int main() {
  std::string count;
  // 1
  std::cout << "Enter a size of array: " << std::endl;
  std::cin >> count;
  foo(std::stoi(count));
  // 2
  std::cout << "Enter a size of array: " << std::endl;
  std::cin >> count;
  foo(std::stoi(count));
  return 0;
}

Не совсем понимаю почему это работает. Ведь для создания массива на стеке assembler заранее должен знать какой размер у этого массива будет. Тут же значение массива не известно, пока его не введет пользователь.
Добрые жители StackOverflow, прошу объясните мне..

Ответы

▲ 4Принят

С простыми типами, какие есть в Си компиляторы прощают нестандартный код и пишут код так-же как в Си. Нужно просто поднять вершину стека на нужное количество байт.

mov     rbp, rsp
push    r12
push    rbx
add     edi, DWORD PTR foo(int)::a[rip]
movsx   rax, edi
mov     DWORD PTR foo(int)::a[rip], edi
lea     rax, [15+rax*4]
and     rax, -16
sub     rsp, rax

Команда lea rax, [15+rax*4] вычисляет нужное число для увеличивания границы вершины стека и простым вычитанием sub rsp, rax это делает.

В Си это до сих пор законно, а в C++ нет. Не рекомендуется писать несовместимо. Другой компилятор просто не сможет это сделать.


Добавление +15 и and -16 нужно для увеличивания вершины, кратным 16.