何时为局部变量分配堆栈空间?

时间:2009-11-06 15:15:07

标签: c stack memory-management

我对以下C代码有疑问:

void my_function()
{
    int i1;
    int j1;

    // Do something...

    if (check_something())
    {
        int i2;
        int j2;

        // Do something else...
    }

    // Do some more stuff...
}

是否有关于何时为i2和j2分配/解除分配堆栈空间或是否依赖于编译器的保证?我希望当i2和j2进入范围时调整堆栈指针,并在它们超出范围时进行调整,但后来认为某些编译器可能只是“优化”整个事物并在嵌套范围内考虑变量。首先输入该功能。

我知道我可以查看我的编译器生成的汇编代码,但是想知道实现是否可以留给编译器。

谢谢!

5 个答案:

答案 0 :(得分:8)

没有保证。

不同的优化标志可能会导致保存变量的不同方法。

编译器甚至可以使一个或多个变量完全不使用堆栈,并在整个函数执行期间将它们保存在寄存器中。

答案 1 :(得分:6)

只要语言的语义 保留,编译器就可以随意做任何事情。换句话说,i2j2可以在执行到达其块的入口点之前绑定到内存位置,并且可以在任何时候无限制,只要这不会影响您的语义。代码。

答案 2 :(得分:4)

据我所知,即使不能保证这些变量在堆栈上分配,它们也可以存储在寄存器中。

你真正可以在这里产生什么影响:

  • 建议编译器使用 register 关键字将变量放入注册。

  • 通过将声明移到尽可能晚的位置来帮助编译器本地化变量范围:

    int f(void )  
    {
        /* var1 and var2 probably use the same place for storage. */
        {
             int var1;
             /* ... do something */
        }

        {
             int var2;
             /* ... do something */
        }
    }


  • 即使给定定义的范围延迟初始化:
{
   int i; /* Yes, you must declare it at the begin of block.

   /* Do something... */

   i = START_VALUE;
   /* But you need it only here and below... */
}

答案 3 :(得分:3)

如果要将变量放在堆栈上,则在函数的第一个语句之前的函数开头分配堆栈空间。堆栈指针将向上(或向下)移动总字节数以存储所有局部变量。

答案 4 :(得分:0)

如果“check_something()”很容易被评估为0,那么整个块将使用足够高的优化级别进行优化。是的,它依赖于编译器。通常,如果您正在检查函数调用的返回值,则不会对其进行优化。解决这个问题的最好方法是编译它,然后实际查看文件的反汇编,以验证您认为实际发生的情况。