为什么编译器不能优化std :: string concat?

fgh*_*ghj 8 c++ string gcc clang

我尝试这么简单的代码:

#include <cstdio>
#include <string>

int main()
{
   const std::string s = std::string("a") + "b";
   puts(s.c_str());
   return 0;
 }
Run Code Online (Sandbox Code Playgroud)

我希望编译器(gcc 4.8.2/clang 3.5.0)优化这样的代码

 int main()
 {
   puts("ab");
   return 0;
 }
Run Code Online (Sandbox Code Playgroud)

但我无法得到这样的结果,我尝试了不同的选项,如"-Ofast"," - flto"," - static-libstdc ++",但总是在反汇编输出中看到三个函数调用:

...
callq  0x4017e0 <_ZNSsC2EPKcRKSaIcE>
... 
callq  0x401690 <_ZNSs6appendEPKc>
...
callq  0x401490 <_ZNSs4_Rep10_M_disposeERKSaIcE>
Run Code Online (Sandbox Code Playgroud)

第一个是调用std :: basic_string,std :: allocator> :: basic_string(char const*,std :: allocator const&).

那么任何编译器都可以将这些代码优化为put("ab"); 或至少"std :: string s("ab");"?

如果没有这样的编译器,是什么使这种优化难以实现?

更新 关于实际使用情况.我在实际代码中看到/看到了许多具有这种模式的地方:

  std::string s = std::string(string_const1) + string_const2 + string_variable + string_const3;
Run Code Online (Sandbox Code Playgroud)

如果性能很重要,当然可以以更优化的方式重写这些代码.

但现代编译器可以很好地完成代码优化.例如,gcc具有malloc/free/strcpy/strcat的__builtin函数,依此类推.如果来自gcc的libstdc ++的std :: basic_string使用它们的函数(malloc,free,strcpy,strcat)进行部分实现,为什么不预测函数使用的结果并给出答案.

Col*_*mbo 7

std::string 涉及存储的动态分配,并且在大多数情况下,涉及极其复杂的实现,因此无论编译器如何经常折叠成美术,都不能简化为编译时语义.

但是:如果您string实际上是这样声明的原因,为什么不首先使用char数组但是选择了string?如果你需要使用一些字符串来生成其他字符串,那么仍然有一些工具可以用char数组来完成这项工作,特别是因为C++ 11引入了可变参数模板和constexpr.未来的C++版本也有望std::string_literal进一步简化.

  • >为什么你不首先使用char数组但是选择了字符串?因为它不是真正的代码,并且在上面出现与上面类似的代码时,不值得手动优化,但我很好奇为什么编译器无法为我优化它. (2认同)