对我来说,C和C++都可以很好地进行尾递归优化,但在调试时,似乎从未看到指示此优化的帧堆栈。这有点好,因为堆栈告诉我递归有多深。然而,优化也会很好。
是否有C++编译器执行此优化?为什么?为什么不?
如何告诉编译器执行它?
- 对于MSVC:
/O2
或/Ox
- 对于GCC:
-O2
或-O3
怎样检查编译器是否在某种情况下执行了此操作?
- 对于MSVC,请启用PDB输出以跟踪代码,然后检查代码
- 对于GCC..?
虽然Konrad告诉我要假设编译器已经执行了此操作,但我仍然希望能够提出一些关于如何确定编译器是否像此优化某个特定函数的建议。
始终可以通过制作无限递归并检查是否导致无限循环或堆栈溢出来检查编译器是否执行此操作(我使用GCC进行了测试,并发现-O2
足够),但我希望能够检查我知道将在任何情况下终止的某个函数。我希望有一种简单的方法来检查这一点:)
经过一些测试,我发现析构函数破坏了使此优化成为可能的可能性。有时更改某些变量和临时变量的作用域以确保它们在返回语句开始之前超出作用域可能值得。
如果任何析构函数需要在尾调用之后运行,则无法进行尾调用优化。
gcc
有一个更窄的选项-foptimize-sibling-calls
,用于"优化兄弟和尾递归调用"。根据针对不同平台版本4.4、4.7和4.8的gcc(1)
手册,此选项在级别-O2
、-O3
、-Os
下启用。 - FooF