我尝试这么简单的代码:
#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)进行部分实现,为什么不预测函数使用的结果并给出答案。
答案 0 :(得分:7)
std::string
涉及存储的动态分配,并且在大多数情况下,涉及极其复杂的实现,因此无论编译器如何经常折叠成美术,都不能简化为编译时语义。
但是:如果您的string
实际上是这样宣布的,那么为什么您首先使用的是char
数组但是选择了string
?
如果您需要使用某些字符串来生成其他字符串,那么仍然可以使用char
数组来完成该工作,尤其是因为C ++ 11引入了可变参数模板和constexpr
。未来的C ++版本有望引入std::string_literal
以进一步简化。