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

Nai*_*ree 4 c stack allocation alloca

引用第2 BUGS节,从手册页alloca(3)

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

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

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

int
main(void)
{
    f(1, alloca(100), 2);
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,alloca将堆栈帧扩展为main100字节(通过修改堆栈指针寄存器),然后指向堆栈存储器块(以及2 int秒)的指针在堆栈帧上传递f.所以分配的空间不应该在中间a,b或者c实际上它应该在不同的帧上(main在这种情况下,它在帧上).

那么这里的误解是什么?

Who*_*aig 7

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

也就是说,考虑一下:

你以前写过编译器吗?函数参数的评估顺序没有标准保证.因此,假设某个平台选择为呼叫构建激活记录,f最终将以下内容从右到左(他们的选择)推入激活堆栈:

  1. 将2推入激活记录堆栈空间.
  2. 执行alloca(100),吸收相同的堆栈,保持呼叫激活记录由额外的100建立char.
  3. 将(2)a的结果推void*入激活记录堆栈空间.
  4. 将1推入激活记录堆栈空间.
  5. 调用call f,将返回地址main压入激活记录堆栈空间.

现在,把自己想象成功能f.您希望在哪里找到函数的第三个参数?嗯....

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