告诉 GCC 尾调用函数

Posted

技术标签:

【中文标题】告诉 GCC 尾调用函数【英文标题】:Telling GCC to tail-call a function 【发布时间】:2019-09-12 14:05:00 【问题描述】:

假设我有一个 C 函数:

unsigned int fact(unsigned int n, unsigned int acc) 
  if(n > 0) return fact(n - 1, n * acc);
  return acc;

有没有办法告诉 GCC 尾调用递归函数,比如

unsigned int fact(unsigned int n, unsigned int acc) 
  if(n > 0) return __tail_call(fact, n - 1, n * acc);
  return acc;

我可以通过将-O2 标志传递给编译器来实现这一点,但我希望尾部调用行为在较低的优化级别,这样我可以更快地编译。

实际的功能要复杂得多,我想使用 TCO,因为它明确了迭代中的哪个状态会影响未来的迭代,以及每次迭代都会重新初始化哪个状态。

编辑:这被标记为 this 的副本,但该线程 a) 没有任何 GCC 答案,并且 b) 不是要在代码中放置一些东西 强制 TCO。

【问题讨论】:

显然名为-foptimize-sibling-calls 的东西应该是“优化同级和尾递归调用。在-O2、-O3、-Os 级别启用。”。我没试过。 哦,很好,谢谢 Lundin。我仍然希望代码中的某些内容来执行此操作,因为它明确说明了何时需要 TCO 才能实现功能。但这绝对是一个足够好的解决方案。 好吧,如果对递归函数是否优化尾调用有任何疑问,正确的解决方案是用循环替换递归。一般来说,这适用于递归。 @vaxquis 我没有将其作为答案发布,因为我之前没有使用过该选项并且不知道该选项有多么有用/错误。我只是在 RTFM 中搜索“tail”,然后看…… @vaxquis 我不会说它们是重复的。另一个问题专门要求执行 TOC。这个问题询问如何在不使用-O2的情况下启用它。 【参考方案1】:

根据https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

-foptimize-sibling-calls

优化兄弟和尾递归调用。

在 -O2、-O3、-Os 级别启用。

在此处进一步阅读:How do I check if gcc is performing tail-recursion optimization?

【讨论】:

以上是关于告诉 GCC 尾调用函数的主要内容,如果未能解决你的问题,请参考以下文章

如何启用递归函数以避免堆栈溢出?

尾调用优化和尾递归改写

函数式编程-尾递归尾调用

尾调用

尾调用优化

尾调用优化