预期的无限递归,没有

无限递归通常是不需要的,当它发生时,通常会导致堆栈溢出或段错误。

但是出于理论和朴素的好奇心,我一直在考虑是否可以有意地创建实际的无限递归。

使用C ++和C工作,通常每个函数调用都会增加堆栈,每个函数都会返回并弹出它处理的堆栈部分。

这是这个想法。 是否有可能强制函数清除它自己的堆栈空间,然后调用另一个函数,以便新函数有效替换第一个函数,而不需要第一个函数需要返回,然后通过循环再次启动。

如果可能的话,我不仅仅将纯循环看作是可能的用途。 循环通常在他们所做的事情上做得很好。 但是如果你用它来通过一个节点网络发送信号,这些信号会在它们自己的进程线程中无限期地继续,直到它们达到一定的条件。 它可能是一个可用于某些问题的工具。

请记住,我并不真正在问是否可行,只有在可能的情况下。 为了科学!


是否有可能强制一个函数清除它自己的堆栈空间,然后调用另一个函数,以便新函数有效地替换第一个函数

这是用于尾巴呼叫优化,所以是的,这是可能的,并在实践中使用。 在像C ++这样的语言中,这是一个很好的特性,因为有时候算法使用递归表达更简单,但是使用循环更有效地实现。 在某些情况下,转换可以由编译器自动完成。


有一种称为蹦床的技术,用于在不使用尾部呼叫优化的情况下实现继续传递式样编程。 如果您认为没有TCO支持的任何语言(如JavaScript)以及该语言的CPS研究解决方案,那么解决方案很可能涉及蹦床。

实质上,在蹦床运动中有一个称为蹦床的功能,它迭代地调用回程功能。

我知道你说“没有第一个函数需要返回然后通过循环再次触发” - 这就是蹦床 - 但考虑到这是C ++,例如,返回范围是C ++核心设计的核心。通过析构函数自动进行资源管理(请参阅:RAII)。 您也可以使用C的setjmp() / longjmp()函数来清除堆栈,但是在确保所有资源都已正确释放时需要非常小心。


这确实让我想起了可以用汇编代码完成的优化。 说你有这个:

  call FuncA
  call FuncB

您可以将其替换为:

  push ReturnAddress
  push FuncB
  jmp FuncA
ReturnAddress:

这会导致FuncA结束时的ret直接跳到FuncB ,而不是返回给调用者,然后返回到FuncB 。 在高级语言中不太可能。

还有这个:

 call FuncA
 ret

可以将其更改为:

 jmp FuncA
链接地址: http://www.djcxy.com/p/80521.html

上一篇: Intended infinite recursion, no

下一篇: How does @tailrec work