gcc:如果我在C ++中返回std :: string,是否没有尾递归?

根据我的回答编写一个反向输入字符串的递归函数,我试着看看clang++ -O3g++ -O3是否会进行尾递归优化,使用一些来自我如何检查gcc是否正在执行的建议尾递归优化?,但它看起来不像是任何尾递归优化发生。 任何想法为什么?

这是否与C ++对象的创建和销毁方式有关? 有什么办法可以使它工作吗?

该计划:

% cat t2.cpp
#include <iostream>
#include <string>

std::string
rerev1(std::string s)
{
        if (s.empty())
                return s;
        return rerev1(s.substr(1)) + s[0];
}

std::string
rerev2(std::string s, std::string b = "")
{
        if (s.empty())
                return b;
        return rerev2(s.substr(1), s[0] + b);
}

int
main()
{
        std::cout << rerev1("testing") << std::endl;
        std::cout << rerev2("testing") << std::endl;
}

测试(如果尾递归优化将发生,我希望只有一个调用每个版本的函数,而不是两个):

% clang++ -Wall -O3 t2.cpp
% objdump --disassemble a.out | fgrep rerev | fgrep callq
  400d8f:       e8 ac ff ff ff          callq  400d40 <_Z6rerev1Ss>
  400fd1:       e8 5a ff ff ff          callq  400f30 <_Z6rerev2SsSs>
  401168:       e8 d3 fb ff ff          callq  400d40 <_Z6rerev1Ss>
  40128d:       e8 9e fc ff ff          callq  400f30 <_Z6rerev2SsSs>

% g++ -O3 t2.cpp
% objdump --disassemble a.out | fgrep rerev | fgrep callq
  400c93:       e8 28 02 00 00          callq  400ec0 <_Z6rerev1Ss>
  400cfa:       e8 11 03 00 00          callq  401010 <_Z6rerev2SsSs>
  400f25:       e8 96 ff ff ff          callq  400ec0 <_Z6rerev1Ss>
  4010ca:       e8 41 ff ff ff          callq  401010 <_Z6rerev2SsSs>

% clang++ -v
Debian clang version 3.0-6.2 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: x86_64-pc-linux-gnu
Thread model: posix

% g++ --version
g++ (Debian 4.7.2-5) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
链接地址: http://www.djcxy.com/p/80751.html

上一篇: gcc: is there no tail recursion if I return std::string in C++?

下一篇: recursion optimization in scala?