为什么一个C / C ++编译器需要在编译时知道数组的大小? [英] Why does a C/C++ compiler need know the size of an array at compile time?

查看:173
本文介绍了为什么一个C / C ++编译器需要在编译时知道数组的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道C类标准preceding C99(以及C ++)说,在栈中的一个数组的大小必须在编译时是已知的。但是,这是为什么?上堆叠阵列在运行时被分配。那么,为什么在编译时的大小重要吗?希望有人向我解释什么是编译器将与大小在编译的时候做的。谢谢。

这种阵列的实例是:

 无效FUNC()
{
    / *这里的阵是在栈中的局部变量,其空间被分配
     *在运行时。为什么编译器需要知道它在编译时的大小?
     * /
   int数组[10];
}


解决方案

要了解为什么可变大小的阵列实现起来更复杂,你需要了解一些变量存储如何自动的持续时间(本地),通常实施

局部变量趋向于被存储在运行时间堆栈上。堆栈基本上是一个大阵列的存储器,其被顺序地分配给局部变量和与单一索引指向当前高水位标记。该指数是的堆栈指针

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

这意味着局部变量在内存中的实际位置仅参考堆栈指针的值在函数入口 1 定义。在功能code必须通过从堆栈指针偏移量访问本地变量。所使用的确切的偏移取决于局部变量的大小。

现在,当所有的局部变量有一个固定在编译时的尺寸,从堆栈指针这些偏移也是固定的 - 所以他们可以直接coded到编译器发出的指令。例如,在这样的功能:

 无效美孚(无效)
{
    int类型的;
    炭B〔10〕;
    INT℃;

A 可能为访问STACK_POINTER + 0 B 可能为 STACK_POINTER + 4 和 C 不妨来访问 STACK_POINTER + 14

不过,当你介绍一个可变大小的数组,这些偏移不再能够在编译时计算;其中一些将取决于该阵列对这个调用的函数的大小而异。这使得事情显著多为编译器作者复杂,因为他们现在必须写入code访问 STACK_POINTER + N - 既然 N 本身变化,它也必须存储在某个地方。通常,这意味着做两次访问 - 一个 STACK_POINTER +<恒定GT; 加载 N ,然后又加载或存储所关心的实际局部变量。


1。事实上,在函数入口堆栈指针的值就是这样一个有用的值有大约,它有它自己的名字 - 帧指针的 - 很多CPU提供一个单独的寄存器专用于存储帧指针。在实践中,它通常是从该局部变量的位置被计算帧指针,而不是堆栈指针本身。

I know C standards preceding C99 (as well as C++) says that the size of an array on stack must be known at compile time. But why is that? The array on stack is allocated at run-time. So why does the size matter in compile time? Hope someone explain to me what a compiler will do with size at compile time. Thanks.

The example of such an array is:

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]; 
}

解决方案

To understand why variably-sized arrays are more complicated to implement, you need to know a little about how automatic storage duration ("local") variables are usually implemented.

Local variables tend to be stored on the runtime stack. The stack is basically a large array of memory, which is sequentially allocated to local variables and with a single index pointing to the current "high water mark". This index is the stack pointer.

When a function is entered, the stack pointer is moved in one direction to allocate memory on the stack for local variables; when the function exits, the stack pointer is moved back in the other direction, to deallocate them.

This means that the actual location of local variables in memory is defined only with reference to the value of the stack pointer at function entry1. The code in a function must access local variables via an offset from the stack pointer. The exact offsets to be used depend upon the size of the local variables.

Now, when all the local variables have a size that is fixed at compile-time, these offsets from the stack pointer are also fixed - so they can be coded directly into the instructions that the compiler emits. For example, in this function:

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

a might be accessed as STACK_POINTER + 0, b might be accessed as STACK_POINTER + 4, and c might be accessed as STACK_POINTER + 14.

However, when you introduce a variably-sized array, these offsets can no longer be computed at compile-time; some of them will vary depending upon the size that the array has on this invocation of the function. This makes things significantly more complicated for compiler writers, because they must now write code that accesses STACK_POINTER + N - and since N itself varies, it must also be stored somewhere. Often this means doing two accesses - one to STACK_POINTER + <constant> to load N, then another to load or store the actual local variable of interest.


1. In fact, "the value of the stack pointer at function entry" is such a useful value to have around, that it has a name of its own - the frame pointer - and many CPUs provide a separate register dedicated to storing the frame pointer. In practice, it is usually the frame pointer from which the location of local variables is calculated, rather than the stack pointer itself.

这篇关于为什么一个C / C ++编译器需要在编译时知道数组的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆