gpt4 book ai didi

c++ - 为什么 C/C++ 编译器需要在编译时知道数组的大小?

转载 作者:IT老高 更新时间:2023-10-28 12:34:05 26 4
gpt4 key购买 nike

我知道 C99(以及 C++)之前的 C 标准规定堆栈上数组的大小必须在编译时知道。但这是为什么呢?堆栈上的数组是在运行时分配的。那么为什么大小在编译时很重要?希望有人向我解释编译器在编译时将如何处理大小。谢谢。

这样一个数组的例子是:

void func()
{
/*Here "array" is a local variable on stack, its space is allocated
*at run-time. Why does the compiler need know its size at compile-time?
*/
int array[10];
}

最佳答案

要了解为什么可变大小的数组实现起来更复杂,您需要了解一下自动存储持续时间(“本地”)变量通常是如何实现的。

局部变量倾向于存储在运行时堆栈中。堆栈基本上是一个大的内存数组,它被顺序分配给局部变量,并有一个指向当前“高水位线”的索引。这个索引是堆栈指针

进入函数时,栈指针向一个方向移动,为局部变量在栈上分配内存;当函数退出时,堆栈指针向另一个方向移回,以释放它们。

这意味着局部变量在内存中的实际位置仅引用函数入口1处的堆栈指针的值来定义。函数中的代码必须通过堆栈指针的偏移量来访问局部变量。要使用的确切偏移量取决于局部变量的大小。

现在,当所有局部变量的大小在编译时固定时,堆栈指针的这些偏移量也是固定的 - 因此它们可以直接编码到编译器发出的指令中。例如,在这个函数中:

void foo(void)
{
int a;
char b[10];
int c;

a可以作为 STACK_POINTER + 0 访问, b可以作为 STACK_POINTER + 4 访问, 和 c可以作为 STACK_POINTER + 14 访问.

但是,当您引入一个可变大小的数组时,这些偏移量就不能再在编译时计算;其中一些将根据数组在函数调用时的大小而有所不同。这使得编译器编写者的事情变得更加复杂,因为他们现在必须编写访问 STACK_POINTER + N 的代码。 - 从 N 开始本身各不相同,它也必须存储在某个地方。这通常意味着进行两次访问——一次访问 STACK_POINTER + <constant>。加载 N ,然后另一个加载或存储感兴趣的实际局部变量。


1.事实上,“函数入口处的堆栈指针的值”是一个非常有用的值,它有自己的名称 - 帧指针 - 许多 CPU 提供了一个单独的寄存器专用于存储帧指针。在实践中,通常是计算局部变量位置的帧指针,而不是堆栈指针本身。

关于c++ - 为什么 C/C++ 编译器需要在编译时知道数组的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4341570/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com