【发布时间】:2018-11-14 02:59:55
【问题描述】:
考虑以下代码:
#include <string>
#include <cstring>
size_t foo(const char* cptr)
{
if (cptr == nullptr) { return 0; }
return strlen(cptr);
}
size_t bar()
{
static const char* cptr { "Hello world" };
return std::string{cptr}.length();
}
size_t baz(const char* cptr)
{
if (cptr == nullptr) { return 0; }
return std::string{cptr}.length();
}
使用 GodBolt,我们 can see 认为 GCC 8.1 和 Clang++ 6.0 可以优化 std::string 在 bar() 中,但不能在 baz() 中。在baz() 中,虽然编译器不能返回一个固定值,但它绝对可以只运行检查字符串长度的代码,而无需构造任何东西,或者至少无需完成构造——即行为类似于foo()。为什么它会完全构造字符串?
【问题讨论】:
-
只要你在任何地方使用
baz,它就会出现。 -
@FrançoisAndrieux:如果它在不同的翻译单元中,则不会。
-
baz("Hello world")将输出与bar()相同的单条指令 -
@ricco19:不在其他翻译单元中不会。
-
尝试使用更长的字符串(比 SSO 大小更长)的 bar,您可能会得到一些不同的东西。字符串的构造函数远非微不足道,如果大小未知,可能很难消除。
标签: c++ g++ compiler-optimization clang++ stdstring