我最近发现了类似于以下几行的内容:
#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::string
转换为bool
;-)
编辑
下面的代码也“适当地”优化为return true;
:
#include <string>
bool test_extension(const std::string& ext) {
return ".foo" || ext == ".bar";
}
这将使您更加困惑:如果我们创建一个自定义字符类型MyCharT
,并使用它来创建自己的自定义std::basic_string
,会发生什么?