Gur*_*lki 9 c java programming-languages
在java或c中,我可以编写一个类似的函数
fun(){
fun();
}
Run Code Online (Sandbox Code Playgroud)
(忽略语法细节)
在java中,我得到了OutOfMemory异常,但是在C(也许还有其他一些语言)中它似乎永远运行,好像它是一个无限循环.为什么我不在这里得到OutOfMemory错误?
Mar*_*ger 12
其他的回答是正确的,有一些编译器魔法将尾递归转换为迭代,尽管它取决于编译器的优化设置.例如,在gcc中,如果我们编译gcc -S -O1 someFile.c(给定你的代码),我们得到以下生成的程序集:
fun:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl $0, %eax
call fun
leave
ret
.LFE2:
.size fun, .-fun
Run Code Online (Sandbox Code Playgroud)
所以你可以看到,它仍然使用call/leave/ret指令来执行实际的函数调用,这会终止进程.一旦你开始进一步优化gcc -S -O2 someFile.c我们开始获得魔力:
fun:
.LFB24:
.p2align 4,,10
.p2align 3
.L2:
jmp .L2
.LFE24:
.size fun, .-fun
.p2align 4,,15
Run Code Online (Sandbox Code Playgroud)
这取决于您的编译器和编译器设置,因此有助于成为他们的朋友.
原因是C编译器可能将其视为尾部重用调用,从而避免构建用于执行函数的堆栈.由于没有为调用构建堆栈,因此它从递归变为简单的无限循环执行.您可以强制它通过使其头部递归来构建堆栈
int fun() { 1 + fun(); }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
560 次 |
| 最近记录: |