【问题标题】:Does C# do tail recursion? [duplicate]C# 做尾递归吗? [复制]
【发布时间】:2011-10-29 11:21:00
【问题描述】:

可能重复:
Why doesn't .net/C# eliminate tail recursion?

C# 做尾递归吗?

我找不到任何文件告诉我是否这样做。

【问题讨论】:

  • C# 规范没有提到 TCO。
  • 我相信它与编译器的关系比语言更多
  • @V4Vendetta 不是这样。编译器(和运行时)只是实现一种语言(可能带有错误、扩展和巧妙的优化)。在没有语言提供的保证的情况下,尝试猜测编译器/运行时/JIT 在给定情况下会做什么(以及在略有不同环境中会做什么)是一个令人愤怒的练习。

标签: c# tail-recursion


【解决方案1】:

C# 本身并不支持该语言中的尾递归,但这里有一个有趣的article,关于类似的技术调用蹦床,它可以帮助您解决您的情况

【讨论】:

    【解决方案2】:

    不幸的是,它没有,至少现在还没有。

    我不确定标准本身是否规定了任何关于 (dis) 允许尾递归的内容。无论如何,由于 .Net 支持尾递归,因此最好将其引入 C#。

    如果您确实需要 .Net 语言中的尾递归,请考虑使用 F#。

    【讨论】:

    • 它 (.NET) 可以。自 CLR 2 以来,32 位和 64 位 JITter 都已完成此操作,但在 .NET 4 中已大大改进。
    • 我仍然想知道为什么尾递归没有直接在 C# 编译器中实现的一个很好的理由。看起来很简单(特别是考虑到尾递归是 .Net 原生的),而且它是一个非常有用的功能,有时需要依赖(好吧,不是 needs 本身,而是宁愿不必写出一个循环)。
    • 那里有点奇怪:) 使用 64 位 JITter,编译器是否为其调用发出 tail. 前缀几乎是无关紧要的。只有少数情况会有所不同(主要例外:如果您禁用了优化,这很重要),因此从编译器的角度来看,这并不重要。 blogs.msdn.com/b/davbr/archive/2007/06/20/… 我不确定 32 位 JITter 的当前行为是什么,但根据上一篇文章 (CLR 2),编译器必须发出前缀才能使其生效。
    • @KenWayneVanderLinde 尾递归优化就是——一种优化。优化尾调用意味着运行时不再能够产生正确的堆栈跟踪(因为优化忽略了一些堆栈帧)。如果 C# 编译器优化了尾调用,那么代码将产生不正确的堆栈跟踪。来源:gbracha.blogspot.cz/2009/12/chased-by-ones-own-tail.html
    • 他是正确的,应该需要优化调用。事实上,CLR 支持尾调用正是因为他的论点 1(在博客末尾)。 “对于 CLR 4,x64 JIT 有时不遵守“尾巴”这一事实。前缀阻止了像 F# 这样的函数式语言的可行性。因此,我们努力改进 x64 JIT,以便它能够尊重“尾部”。始终使用前缀并帮助 F# 取得成功。” blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-30
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-04
    • 2011-02-11
    相关资源
    最近更新 更多