最终尾调用递归问题

时间:2010-02-19 00:31:41

标签: .net tail-call-optimization

参加this fiascoquestion的辩论后,我想在整个社区面前提出这个问题。

在什么情况下,尾调用优化应用于基于.Net的代码?

请通过可靠,最新的来源或可重复的实验来支持您的答案。

1 个答案:

答案 0 :(得分:4)

根据Don Syme等人撰写的“Expert F#”,F#进行尾调用优化。我似乎记得在Eric Lippert的博客上读到C#编译器(任何版本)都没有。如果我错了,请纠正我,埃里克。在所有情况下,当最后一条指令要调用方法时,可以进行尾调用优化。这通常是方法本身的递归调用,但不是必须的。可以完成优化,因为它保证不再需要当前的堆栈帧。但是,如果之后只需执行简单操作,则无法执行优化。

int Fib(int n)
{
  if(n < 2)
     return 1;

  return Fib(n-1) + Fib(n-2);
}

这不能进行尾调用优化,因为在+的最后一次调用返回之前无法评估Fib。 (实际上我认为这是专家F#中使用的例子,但不确定那个。)

int Fib(int n, int a, int b)
{
  if(n == 0)
    return a+b;
  return Fib(n-1,a+b,a);
}

此版本可以进行尾调用优化,因为在最后一次调用Fib之前评估所有参数,并且在调用之后不存在要执行的操作,因此可以丢弃当前堆栈帧。