g++/gcc是否能够展开递归内联函数?

g++/gcc是否能够展开递归内联函数?,gcc,recursion,profiling,g++,stack-trace,Gcc,Recursion,Profiling,G++,Stack Trace,我有一个递归函数,但不是尾部递归内联函数,我希望gcc为其展开递归。是的,我当然使用了g++-O3-funroll循环 inline void recurse_fun(..., unsigned depth = 0, unsigned max_depth = 40) { if (++depth > max_depth) return; for (auto i = ..., iend = ...; i != iend; i++) { if (...) cont

我有一个递归函数,但不是尾部递归内联函数,我希望gcc为其展开递归。是的,我当然使用了
g++-O3-funroll循环

inline void recurse_fun(..., unsigned depth = 0, unsigned max_depth = 40) {
    if (++depth > max_depth) return;
    for (auto i = ..., iend = ...; i != iend; i++) {
        if (...) continue;
        ...
        recurse_fun(...,depth,max_depth);
    }
}
我可以通过手动处理
堆栈
对象来轻松地替换它,gcc应该正确地展开该对象,但它不会那么优雅或可维护

不管怎样,我真的应该尝试分析这两个版本,但我很好奇是否有人可以自信地说,一些最新的gcc版本会或不会正确处理这个问题

GCC(至少是像4.5或4.6这样的最新版本)确实展开了一些尾部递归调用。 当然,您需要要求它进行优化(因此需要
-O2
-O3

要了解它在做什么,你可以

  • 使用类似于
    gcc-O3-fverbose asm-S yoursource.c的内容请求程序集输出
  • 请求各种类型的文件,比如gcc-c-fdump tree all-fdump ipa all-O3 yoursource.c
(还有其他转储文件) 请注意,GCC将打印大量(数百!)转储文件。转储文件仅用于帮助GCC开发人员或GCC插件开发人员(或开发人员)。不要期望从一个GCC版本到下一个GCC版本都保持相同的格式

转储文件的编号是无用的:它不是按时间顺序或逻辑排列的


在下一个GCC版本(4.7,可能在2012年)中,转储选项可能会发生变化。

相关:您能看看生成的汇编语言吗?此外,1)任何这样做的函数都不会从内联中看到什么好处,2)编译器是否内联递归函数?那会让我吃惊的。3) 如果你的意思是展开内部循环,那么如果内部有函数调用,也不会节省太多是的,我想阅读汇编程序要比使用剖析器Mike Dunlavey容易得多。