当变量超出范围时,有没有办法强制 gcc 从堆栈中释放空间

Lou*_*ron 7 c gcc stack-allocation

我有以下代码:

extern void func1(char *array);
extern void func2(char *array);

void myfunction(void) {
    if (somecondition) {
        char var2[256];
        func2(var2);
    }
    if (someothercondition) {
    {
        char var3[3];
        func3(var3);
    }
}
Run Code Online (Sandbox Code Playgroud)

我无法让编译器 (gcc)只使用堆栈中func3使用的 3 个字节进行调用。它总是为调用范围中使用的变量var3分配空间,即使该变量超出范围并且可以安全地从堆栈中删除。var2func2

我尝试了在 gcc 文档中找到的几个选项:

  • fomit-frame-pointer
  • fconserve-stack

我已经在 x86 和 ARM 架构上尝试过了,它的行为是相同的。

这个问题背后的基本原理是仅使用必要的堆栈大小。

以及相关的问题:如果可以优化堆栈空间,是否可以在选项生成的.su文件中添加每个子函数调用使用的堆栈-fstack-usage

谢谢

小智 1

你可以这样做:

extern void func1(char *array);
extern void func2(char *array);

void _helper(/* neccessary parameters */)
{
    char var2[256];
    func2(var2);
}

void myfunction(void) {
    if (somecondition) {
        _helper(/* neccessary parameters */);
    }
    if (someothercondition) {
    {
        char var3[3];
        func3(var3);
    }
}
Run Code Online (Sandbox Code Playgroud)

_helper因为分配发生在不同的函数中,所以编译器只会在调用时分配内存。这可能容易受到优化(内联)的影响,但将帮助程序移动到不同的编译单元(新的 c 文件)将阻止这种情况。

当然,这会以函数调用和参数复制为代价。

无论如何,如果堆栈空间问题与递归有关,您应该考虑将其替换为使用显式预分配堆栈的迭代解决方案。