Почему нельзя использовать alloca в списке аргументов функции?

Цитируя второй абзац BUGS раздел, с manpage из alloca(3)

На многих системах alloca() не может использоваться внутри списка аргументов вызова функции, потому что пространство стека зарезервировано alloca() появится в стеке в середине пространства для аргументов функции.

Я не видел, как это произойдет. Взяв следующий код в качестве примера:

void f(int a, void * b, int c);

int
main(void)
{
    f(1, alloca(100), 2);
}

Исходя из моего понимания, alloca расширяет кадр стека для main на 100 байт (путем изменения регистра указателя стека), затем указатель на этот блок памяти стека (вместе с 2 ints) передается в кадре стека для f, Таким образом, выделенное пространство не должно быть в середине a, b или же cна самом деле это должно быть в другом кадре (который находится на кадре для main в этом случае).

Так в чем здесь недоразумение?

1 ответ

Решение

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

Тем не менее, рассмотрим это:

Вы когда-нибудь писали компилятор раньше? Нет стандартной гарантии порядка вычисления аргументов функции. Поэтому предположим, что какая-то платформа решила создать запись активации для вызова f в конечном итоге, вставив в стек активации справа налево (их выбор):

  1. Вставляет 2 в пространство стека записи активации.
  2. Выступает alloca(100), который сосет тот же стек, содержащий запись активации вызова, создаваемую дополнительными 100 char,
  3. Толкает результат (2), а void* в пространство стека записей активации.
  4. Вставляет 1 в пространство стека записи активации.
  5. Запускает call f который выдвигает обратный адрес в main в пространство стека записи активации.

Теперь думайте о себе как о функции f, Где вы ожидаете найти третий параметр вашей функции? Эм....

Это только один пример того, как можно бросить alloca место где-то, что может вызвать проблемы.

Другие вопросы по тегам