【发布时间】:2014-04-20 20:32:51
【问题描述】:
堆栈溢出的原因是堆栈空间用完了,但是如果函数没有参数,因此不必将数据压入堆栈怎么办?这仍然会推动“返回”地址,但在 预期 无限递归的情况下,这是不必要的。
所以我想问的是......是否可以使用某种调用约定,即调用不会将任何东西放在堆栈上,只是跳转到第一条指令并执行,并提供最后的指令将是对函数的另一个调用,直到最终终止执行?理想情况下,这是否可以通过函数指针和动态链接来实现?
只是为了说明,我指的是一个接受单个参数并且不返回任何内容的函数,因此从技术上讲 fastcall 就足够了,但它仍然保留了要返回的地址,这最终会导致溢出。可以通过某种方式防止这种情况发生吗?
我之前没有提到的另一个重要点,我不是指单个函数的递归,例如在状态是静态且正在被重用的情况下,我的意思是从一个任意函数递归到另一个函数。
【问题讨论】:
-
据我所知不在 C++ 中.. 你需要 C++/C 目前不支持的 Tail Recursion(至少作为标准的一部分)
-
我不认为有 is 没有将任何内容放入堆栈的调用约定。 MSDN's calling-convention docs 展示了一堆不同的调用约定,但最终都使用堆栈(少数先使用寄存器)。
-
为了澄清@Mgetz 的评论,C 和 C++ 标准都不需要支持尾调用,但它们都允许,并且当前的编译器能够支持。
-
“采用单个参数”,如果不在堆栈上,应该存储在哪里?
-
@alk 这将是实现它的一种方法,但很可能编译器只是将函数体更改为循环,而不需要递归调用。实现尾递归并不难,难的是检测它适用的情况。
标签: c++ c recursion stack-overflow calling-convention