开发者

tail recursion stack overflow

As far as I understand开发者_开发问答, a tail recursive function calls itself at the very last step (like the return statement) however, the first instance of the function is not terminated until all the other instances are terminated as well, thus we get a stack overflow after a number of instances are reached. Given that the recursion is at the very last step, is there any way to terminate the previous instance during or right before the next instance? If the only purpose of an instance is to call the next one, there is no reason why it should reside in memory, right?


Yes, some compilers will optimize tail recursion so that it doesn't require extra stack space. For example, let's look at this example C function:

int braindeadrecursion(int n)
{
  if (n == 0)
    return 1;

  return braindeadrecursion(n - 1);
}

This function is pretty easy; it just returns 1. Without optimizations, clang generated code on my machine that looks like this:

_braindeadrecursion:
00  pushq   %rbp
01  movq    %rsp,%rbp
04  subq    $0x10,%rsp
08  movl    %edi,0xf8(%rbp)
0b  movl    0xf8(%rbp),%eax
0e  cmpl    $_braindeadrecursion,%eax
11  jne 0x0000001c
13  movl    $0x00000001,0xfc(%rbp)
1a  jmp 0x0000002e
1c  movl    0xf8(%rbp),%eax
1f  subl    $0x01,%eax
22  movl    %eax,%edi
24  callq   _braindeadrecursion
29  movl    %eax,%ecx
2b  movl    %ecx,0xfc(%rbp)
2e  movl    0xfc(%rbp),%eax
31  addq    $0x10,%rsp
35  popq    %rbp
36  ret

As you can see, the recursive call is in there at 0x24. Now, let's try with higher optimization:

_braindeadrecursion:
00  pushq   %rbp
01  movq    %rsp,%rbp
04  movl    $0x00000001,%eax
09  popq    %rbp
0a  ret

Now, look at that - no more recursion at all! This example is pretty simple, but the optimization can still occur on more complicated tail recursive cases.


Either: - you can increase the stack size or - do not use recursion, but instead use some sort of looping.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜