关于调用自身的函数的堆栈重用?

laz*_*ack 7 c stack-overflow gcc function frame

如果函数在同时定义变量时调用自身会导致堆栈溢出吗?gcc中是否有任何选项可以重用相同的堆栈.

void funcnew(void)
{
   int a=10;
   int b=20;
   funcnew();
   return ;
 }
Run Code Online (Sandbox Code Playgroud)

函数可以重用它之前使用的堆栈帧吗?gcc中的选项是什么在尾递归中重用相同的帧?

APr*_*mer 5

是.看到

-foptimize同胞通话

优化兄弟和尾部递归调用.

在-O2,-O3,-Os等级启用.

您的函数编译为:

funcstack:
.LFB0:
    .cfi_startproc
    xorl    %eax, %eax
    jmp func
    .cfi_endproc
Run Code Online (Sandbox Code Playgroud)

(注意跳转到func)

重用堆栈帧时通过调用一个函数结束 - 这包括其全一般性操作堆栈把参数在正确的位置,并通过跳转替换函数调用的函数的开始 - 是一个众所周知的称为[i]尾部呼叫删除的优化[/ i].一些语言(例如方案)强制要求递归调用(递归调用是在这些语言中表达循环的自然方式).如上所述,gcc已经为C实现了优化,但是我不确定哪个编译器有它,我不会依赖它来获取可移植代码.请注意,我不知道它有哪些限制 - 我不确定gcc是否会在参数类型不同的情况下操纵堆栈.


Joh*_*ler 0

不,每次递归都是一个新的堆栈帧。如果递归无限深,那么所需的堆栈也是无限的,因此会出现堆栈溢出。