Tail会调用优化工作来递归调用返回void的函数吗?例如,我有一个函数, void fun()
void fun()
{
...
...
...
fun();
}
这里编译器不会知道,调用fun()是最后一个语句。那么尾部调用优化仅针对返回某些值的函数进行吗?
答案 0 :(得分:1)
答案是肯定的,它可以,但编译器没有义务这样做。它是否取决于功能,编译器和选定的优化级别。如果您对特定函数关注此问题,请查看特定编译器在特定优化级别生成的程序集。
更具体地说,GCC(至少是使用LLVM作为后端的Apple版本)将为至少一些在优化级别void
或更好的情况下返回-O1
的函数生成尾调用优化代码
一些测试代码:
/* Fills an array with a single value, recursively with side effects */
void fillarray(int val, int* curr, int* end)
{
if (curr==end) return;
*curr = val;
fillarray(val,curr+1,end);
}
通过最小化优化(-O1
),编译到程序集(gcc -O1 -S test.c
)会产生一个很好的尾调用优化函数:
_fillarray:
pushq %rbp
movq %rsp, %rbp # set up the stack
cmpq %rdx, %rsi # early exit if beg == end
je LBB1_2
LBB1_1:
movl %edi, (%rsi) # *curr = val
addq $4, %rsi # curr++
cmpq %rsi, %rdx # TAIL CALL optimization is here
jne LBB1_1 # if curr != end, go to LBB1_1
LBB1_2:
popq %rbp # restore the stack and exit
ret
(注意:我已经删除了一些不必要的标签和对齐语句,这些语句会掩盖组件的结构。)
此外,当关闭优化(-O0
)时,生成的代码是递归的(而不是尾调用优化)。