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

C 何时为局部变量分配堆栈空间?,c,stack,memory-management,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分配/释放堆栈空间的保证,或

我对以下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进入作用域时,堆栈指针会向下调整,当它们离开作用域时,堆栈指针会向上调整,但随后我认为一些编译器可能只是“优化”了整个过程,并在首次输入函数时考虑嵌套作用域中的变量

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


谢谢

没有保证

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


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

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

你在这里真正能影响什么:

  • 建议编译器使用register关键字放置要注册的变量

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

int f(无效) { /*var1和var2可能使用相同的存储位置*/ { int-var1; /*…做点什么*/ } { int-var2; /*…做点什么*/ } }

  • 即使给定定义的范围延迟初始化:
{ int i;/*是,必须在块的开头声明它。 /*做点什么*/ i=起始值; /*但你只需要在这里和下面*/ }
只要语言的语义是保留的,编译器就可以自由地执行它想要的任何操作。换句话说,
i2
j2
可以在执行到达其块的入口点之前绑定到内存位置,并且可以在任何时候不绑定,只要这不影响代码的语义。

如果“check_something()”很容易计算为0,整个区块将使用足够高的优化级别进行优化。是的,它依赖于编译器。通常,如果您正在检查函数调用的返回值,则不会对其进行优化。实现这一点的最佳方法是对其进行编译,并实际查看文件的反汇编,以验证您认为正在发生的事情是否正在实际发生。

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

也考虑变量可以分配给寄存器… 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... */ }