编译器如何解析变长数组后声明的变量的地址?

时间:2014-07-28 06:41:25

标签: c compiler-construction compilation c99 variable-length-array

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

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

编译器如何确定var2的地址?

我能想到的唯一方法是在arrvar1之后放置var2

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

将所有这些放在"正常"之后变量只会帮助解析第一个地址。

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

我意识到它没有被C99标准定义,所以问题实质上是关于编译。

2 个答案:

答案 0 :(得分:2)

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

步骤2:以正常方式为非可变大小的项目分配空间。

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

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

答案 1 :(得分:1)

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

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

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

请注意,这只是一个例子。每个编译器都可以自由地实现VLA,但它很高兴。如果您想知道 编译器的作用,请查看生成的汇编代码。