gpt4 book ai didi

c++ - 与编译时未解析的字符串文字进行比较

转载 作者:行者123 更新时间:2023-12-02 02:36:02 28 4
gpt4 key购买 nike

我最近发现了类似于以下几行的内容:

#include <string>

// test if the extension is either .bar or .foo
bool test_extension(const std::string& ext) {
return ext == ".bar" || ".foo";
// it obviously should be
// return ext == ".bar" || ext == ".foo";
}
<小时/>

该函数显然没有按照注释的建议执行操作。但这不是重点。请注意,这不是 Can you use 2 or more OR conditions in an if statement? 的重复项因为我完全知道如何正确编写该函数!

<小时/>

我开始想知道编译器会如何处理这个片段。我的第一直觉是,这将被编译为 return true; 基本上。将示例插入 godbolt ,表明 GCC 9.2 和 clang 9 都没有通过优化 -O2 进行此优化。

但是,将代码更改为1

#include <string>

using namespace std::string_literals;

bool test_extension(const std::string& ext) {
return ext == ".bar"s || ".foo";
}

似乎可以解决问题,因为装配现在本质上是:

mov     eax, 1
ret

所以我的核心问题是:是否有一些我错过的东西不允许编译器对第一个代码段进行相同的优化?

<小时/>

1使用 ".foo"s 这甚至无法编译,因为编译器不想转换 std::stringbool ;-)

<小时/>

编辑

以下代码也得到“适当”优化,以返回 true;:

#include <string>

bool test_extension(const std::string& ext) {
return ".foo" || ext == ".bar";
}

最佳答案

这会让您更加困惑:如果我们创建自定义字符类型 MyCharT 并使用它来制作我们自己的自定义 std::basic_string 会发生什么?

#include <string>

struct MyCharT {
char c;
bool operator==(const MyCharT& rhs) const {
return c == rhs.c;
}
bool operator<(const MyCharT& rhs) const {
return c < rhs.c;
}
};
typedef std::basic_string<MyCharT> my_string;

bool test_extension_custom(const my_string& ext) {
const MyCharT c[] = {'.','b','a','r', '\0'};
return ext == c || ".foo";
}

// Here's a similar implementation using regular
// std::string, for comparison
bool test_extension(const std::string& ext) {
const char c[] = ".bar";
return ext == c || ".foo";
}

当然,自定义类型不能比普通 char 更容易优化,对吗?

这是最终的组装结果:

test_extension_custom(std::__cxx11::basic_string<MyCharT, std::char_traits<MyCharT>, std::allocator<MyCharT> > const&):
mov eax, 1
ret
test_extension(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
sub rsp, 24
lea rsi, [rsp+11]
mov DWORD PTR [rsp+11], 1918984750
mov BYTE PTR [rsp+15], 0
call std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(char const*) const
mov eax, 1
add rsp, 24
ret

See it live!

<小时/>

Mindblown!

那么,我的“自定义”字符串类型和 std::string 之间有什么区别?

小字符串优化

至少在 GCC 上,Small String Optimization实际上编译成 libstdc++ 的二进制文件。这意味着,在编译函数期间,编译器无法访问此实现,因此它无法知道是否有任何副作用。因此,它无法优化对 compare(char const*) 的调用。我们的“自定义”类不存在此问题,因为 SSO 仅针对普通 std::string 实现。

顺便说一句,如果使用 -std=c++2a 编译, the compiler does optimize it away 。不幸的是,我对 C++ 20 还不够了解,还不知道哪些变化使这成为可能。

关于c++ - 与编译时未解析的字符串文字进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59158594/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com