编译器进行尾递归优化

编译器进行尾递归优化

本文介绍了哪些(如果有)C++ 编译器进行尾递归优化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我看来,在 C 和 C++ 中进行尾递归优化会非常有效,但是在调试时我似乎从未看到指示这种优化的帧堆栈.这很好,因为堆栈告诉我递归有多深.但是,优化也会很好.

It seems to me that it would work perfectly well to do tail-recursion optimization in both C and C++, yet while debugging I never seem to see a frame stack that indicates this optimization. That is kind of good, because the stack tells me how deep the recursion is. However, the optimization would be kind of nice as well.

是否有任何 C++ 编译器进行此优化?为什么?为什么不呢?

Do any C++ compilers do this optimization? Why? Why not?

我该如何告诉编译器这样做?

How do I go about telling the compiler to do it?

  • 对于 MSVC:/O2/Ox
  • 对于 GCC:-O2-O3
  • For MSVC: /O2 or /Ox
  • For GCC: -O2 or -O3

在某种情况下如何检查编译器是否这样做了?

How about checking if the compiler has done this in a certain case?

  • 对于 MSVC,启用 PDB 输出以便能够跟踪代码,然后检查代码
  • 对于海湾合作委员会......?

我仍然会就如何确定某个函数是否被编译器这样优化提出建议(尽管我发现 Konrad 告诉我假设它让我放心)

I'd still take suggestions for how to determine if a certain function is optimized like this by the compiler (even though I find it reassuring that Konrad tells me to assume it)

始终可以通过进行无限递归并检查它是否导致无限循环或堆栈溢出来检查编译器是否完全执行此操作(我使用 GCC 执行此操作并发现 -O2 就足够了),但我希望能够检查某个我知道无论如何都会终止的函数.我很想有一个简单的方法来检查这个:)

It is always possible to check if the compiler does this at all by making an infinite recursion and checking if it results in an infinite loop or a stack overflow (I did this with GCC and found out that -O2 is sufficient), but I want to be able to check a certain function that I know will terminate anyway. I'd love to have an easy way of checking this :)

经过一些测试,我发现析构函数破坏了进行这种优化的可能性.有时值得更改某些变量和临时变量的范围,以确保它们在 return 语句开始之前超出范围.

After some testing, I discovered that destructors ruin the possibility of making this optimization. It can sometimes be worth it to change the scoping of certain variables and temporaries to make sure they go out of scope before the return-statement starts.

如果在尾调用之后需要运行任何析构函数,则无法进行尾调用优化.

If any destructor needs to be run after the tail-call, the tail-call optimization can not be done.

推荐答案

目前所有主流编译器都执行尾调用优化相当不错(并且已经这样做了十多年),甚至对于相互递归调用,例如:

All current mainstream compilers perform tail call optimisation fairly well (and have done for more than a decade), even for mutually recursive calls such as:

int bar(int, int);

int foo(int n, int acc) {
    return (n == 0) ? acc : bar(n - 1, acc + 2);
}

int bar(int n, int acc) {
    return (n == 0) ? acc : foo(n - 1, acc + 1);
}

让编译器进行优化很简单:只需打开优化以提高速度:

Letting the compiler do the optimisation is straightforward: Just switch on optimisation for speed:

  • 对于 MSVC,使用 /O2/Ox.
  • 对于 GCC、Clang 和 ICC,使用 -O3

检查编译器是否进行了优化的一种简单方法是执行一个否则会导致堆栈溢出的调用——或者查看程序集输出.

An easy way to check if the compiler did the optimisation is to perform a call that would otherwise result in a stack overflow — or looking at the assembly output.

作为一个有趣的历史记录,在 毕业论文,作者:Mark Probst.该论文描述了实施中的一些有趣的注意事项.值得一读.

As an interesting historical note, tail call optimisation for C was added to the GCC in the course of a diploma thesis by Mark Probst. The thesis describes some interesting caveats in the implementation. It's worth reading.

这篇关于哪些(如果有)C++ 编译器进行尾递归优化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 04:11