为什么不能在函数参数列表中使用alloca?

时间:2017-01-29 10:03:19

标签: c stack allocation alloca

BUGS

的联构帮助页引用alloca(3)部分的第二段
  

在许多系统上alloca()不能在函数调用的参数列表中使用,因为堆栈          由alloca()保留的空间将出现在函数参数空间中间的堆栈中。

我没看到这会怎么样。以下面的代码为例:

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

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

根据我的理解,allocamain的堆栈帧向下扩展100个字节(通过修改堆栈指针寄存器),然后指向堆栈内存块的指针(以及2 {{1} s)在int的堆栈帧上传递。因此,分配的空间不应位于fab的中间,实际上它应该位于不同的帧({{1}的帧上)在这种情况下)。

那么这里的误解是什么?

1 个答案:

答案 0 :(得分:6)

首先,请立即注意alloca is not standard。它是平台的扩展,希望为程序员提供更多的方法来通过潜在动态消耗自动变量空间来保持自己,以便在速度超过基于其他技术的慢动态内存分配器(堆等)的速度。 (是的,我的意见,但其中有很多真相)。

那就是说,考虑一下:

您以前编写过编译器吗? There is no standard guarantee of evaluation order of function arguments。因此,假设某个平台选择构建activation record来调用f,最终将以下内容从右到左(他们的选择)推送到激活堆栈中:

  1. 将2推入激活记录堆栈空间。
  2. 执行alloca(100),其中相同的堆栈保持呼叫激活记录由额外的100 char构建。
  3. 将(2)的结果(void*)推入激活记录堆栈空间。
  4. 将1推入激活记录堆栈空间。
  5. 调用call f,将main中的返回地址推送到激活记录堆栈空间。
  6. 现在,将自己视为函数f。您希望在哪里找到函数的第三个参数?嗯....

    这只是一个如何在可能导致问题的地方抛出alloca空间的例子。