预期的无限递归、无返回函数
无限递归通常是不希望的,当它发生时,通常会导致堆栈溢出或段错误。
但出于理论的考虑和纯粹的好奇心,我一直在思考是否有可能有意地创建实际的无限递归。
在 C++ 和 C 中工作,堆栈通常会随着每个函数调用而增长,并且每个函数都会返回并弹出它处理的堆栈部分。
这是我的想法。是否可以强制一个函数清除它自己的堆栈空间,然后调用另一个函数,以便新函数有效地替换第一个函数,而不需要第一个函数返回并通过循环再次触发。
我不仅考虑将普通循环作为可能的用途(如果有的话)。循环通常能很好地完成它们所做的事情。但是,如果您使用它通过节点网络发送信号,这些信号在自己的进程线程中无限期地进行,直到达到特定条件,该怎么办?它可能是一个可用于解决某些问题的工具。
请记住,我并不是真的在问是否实用,只是问是否可以做到。为了科学!
Infinite recursion is most often not desired, and when it happens it usually causes a stack overflow or segfaults.
But for theory's sake, and plain curiosity, I've been thinking if it'd be possible to create actual infinite recursion, intentionally.
Working in C++ and C where the stack, usually, grows for each function call, and each function returns and pops the part of the stack it handled.
Here's the thought. Would it be possible to force a function to clear out it's own stack space and then call another function so that the new function effectively replaces the first function, without the first function needing to return and then fire again via a loop.
I'm not only thinking about plain loops as a possible use for this, if there would be any. Loops usually do a good job at what they do. But what if you were to use it for sending signals through a node network, that carry on indefinitely in their own process threads until they reach a certain condition. It might be a tool that could be used for some problems.
Remember, I'm not really asking if it's practical, only if it's possible to do. For science!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它用于 tail-call-optimization,所以是的,这是可能的并在实践中使用。在像 C++ 这样的语言中,这是一个很好的功能,因为有时使用递归表达算法更简单,但使用循环实现更有效。在某些情况下,转换可以由编译器自动完成。
This is used for tail-call-optimization, so yes, it is possible and used in practice. In languages like C++ this a nice feature, because sometimes algorithms are simpler to express using recursion, but more efficiently implemented using a loop. The transformation can in some cases be done automatically by the compiler.
有一种称为蹦床的技术,用于实现连续传递风格不使用尾部调用优化的编程。如果您考虑任何不支持 TCO 的语言(例如 JavaScript),并研究该语言的 CPS 解决方案,那么该解决方案很可能涉及蹦床。
本质上,对于蹦床,有一个称为蹦床的函数,它迭代地调用 thunk 返回函数。
我知道你说过“第一个函数不需要返回,然后通过循环再次触发”——这就是蹦床——但考虑到这是 C++,通过返回来离开作用域是 C++ 核心设计的核心通过析构函数进行自动资源管理(参见:RAII)。您也可以使用 C 的
setjmp()
/longjmp()
函数来清除堆栈,但是您需要非常小心,以确保正确释放所有资源。There is a technique called trampolining that is used to implement continuation-passing style programming without the use of tail-call optimization. If you consider any language without support for TCO, such as JavaScript, and research solutions for CPS in that language, then it is likely that the solution involves trampolining.
Essentially, with trampolining there is a function called a trampoline which iteratively calls thunk-returning functions.
I know that you said "without the first function needing to return and then fire again via a loop"—that's what trampolining is—but considering that this is C++, leaving scopes by, for example, returning is central to the core design of C++'s automatic resource management via destructors (see: RAII). You could alternatively use C's
setjmp()
/longjmp()
functions to wipe out stack, but then you would need to be very careful in making sure that all resources are released properly.这确实让我想起了可以在汇编代码中完成的优化。假设您有这个:
您可以将其替换为:
这会导致
FuncA
末尾的ret
直接跳转到FuncB
而不是返回到调用者,然后进入FuncB
。在高级语言中实际上不可能。还有这个:
可以改成:
This does remind me of an optimisation that can be done in assembler code. Say you have this:
you can replace it with:
This causes the
ret
at the end ofFuncA
to jump toFuncB
directly rather than back to the caller and then ontoFuncB
. Not really possible in higher level languages.There's also this:
which can be changed to: