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

时间:2014-11-04 00:34:32

标签: c++ string gcc clang

我尝试这么简单的代码:

#include <cstdio>
#include <string>

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

我希望编译器(gcc 4.8.2 / clang 3.5.0)将此类代码优化为

 int main()
 {
   puts("ab");
   return 0;
 }

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

...
callq  0x4017e0 <_ZNSsC2EPKcRKSaIcE>
... 
callq  0x401690 <_ZNSs6appendEPKc>
...
callq  0x401490 <_ZNSs4_Rep10_M_disposeERKSaIcE>

第一个是调用std :: basic_string,std :: allocator&gt; :: basic_string(char const *,std :: allocator const&amp;)。

所有编译器都可以将这些代码优化为put(“ab”); 或至少“std :: string s(”ab“);”?

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

更新 关于现实世界的用法。 我在实际代码中看到/看到了许多具有这种模式的地方:

  std::string s = std::string(string_const1) + string_const2 + string_variable + string_const3;

如果表现很重要,当然可以重写 这种代码以更优化的方式。

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

1 个答案:

答案 0 :(得分:7)

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

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