3

假设我有以下函数,它使用可变长度数组:

void func(int size)
{
    int var1;
    int arr[size];
    int var2;
    ...
}

编译器如何确定的地址var2

我能想到的唯一方法是放在andarr之后。var1var2

但是在那种情况下,如果有几个变长数组呢?

将它们全部放在“正常”变量之后只会有助于解析第一个变量的地址。

我在这里的隐含假设是所有局部变量(包括 VLA)都分配在堆栈上。

我意识到它不是由 C99 标准定义的,所以问题本质上是关于编译的。

4

2 回答 2

2

第 1 步:对于每个可变大小的项目,创建一个包含指向数组的指针的隐藏变量,以及一个保存数组大小的隐藏变量。这些可以被优化掉,作为任何其他变量分配给寄存器等。

第 2 步:以正常方式为非可变尺寸项目分配空间。

第 3 步:要处理可变大小项的声明,评估大小并将其存储到大小变量中。计算可变大小项目的空间,同时考虑对齐。在堆栈上为可变大小的项目腾出空间,然后将指向项目位置的指针存储到隐藏指针变量中。

第 4 步:使用隐藏指针变量访问数组元素。对 sizeof 运算符使用隐藏的大小变量。

于 2014-07-28T06:55:14.323 回答
1

这是一种可能的模型。将arr其视为指向堆栈分配数组的(固定大小)指针:

int var1;
int *arr = alloca(sizeof(int) * size);
int var2;

请注意三个变量的(相对)位置如何不随size. 该模型很容易推广到多个 VLA。

请注意,这只是一个示例。每个编译器都可以随意实现 VLA。如果您想知道您的编译器做了什么,请查看生成的汇编代码。

于 2014-07-28T06:44:26.187 回答