考虑以下constexpr
函数,static_strcmp
它使用 C++17 的constexpr
char_traits::compare
函数:
#include <string>
constexpr bool static_strcmp(char const *a, char const *b)
{
return std::char_traits<char>::compare(a, b,
std::char_traits<char>::length(a)) == 0;
}
int main()
{
constexpr const char *a = "abcdefghijklmnopqrstuvwxyz";
constexpr const char *b = "abc";
constexpr bool result = static_strcmp(a, b);
return result;
}
godbolt显示这在编译时得到评估,并优化为:
main: xor eax, eax ret
constexpr
从中删除bool result
:
如果我们删除constexpr
from constexpr bool result
,现在调用不再优化。
#include <string>
constexpr bool static_strcmp(char const *a, char const *b)
{
return std::char_traits<char>::compare(a, b,
std::char_traits<char>::length(a)) == 0;
}
int main()
{
constexpr const char *a = "abcdefghijklmnopqrstuvwxyz";
constexpr const char *b = "abc";
bool result = static_strcmp(a, b); // <-- note no constexpr
return result;
}
Godbolt显示我们现在调用memcmp
:
.LC0: .string "abc" .LC1: .string "abcdefghijklmnopqrstuvwxyz" main: sub rsp, 8 mov edx, 26 mov esi, OFFSET FLAT:.LC0 mov edi, OFFSET FLAT:.LC1 call memcmp test eax, eax sete al add rsp, 8 movzx eax, al ret
添加短路length
检查:
如果我们在调用之前char_traits::length
先比较in 中的两个参数,而没有on ,则调用会再次被优化掉。static_strcmp
char_traits::compare
constexpr
bool result
#include <string>
constexpr bool static_strcmp(char const *a, char const *b)
{
return
std::char_traits<char>::length(a) == std::char_traits<char>::length(b)
&& std::char_traits<char>::compare(a, b,
std::char_traits<char>::length(a)) == 0;
}
int main()
{
constexpr const char *a = "abcdefghijklmnopqrstuvwxyz";
constexpr const char *b = "abc";
bool result = static_strcmp(a, b); // <-- note still no constexpr!
return result;
}
Godbolt显示我们回到了被优化的调用:
main: xor eax, eax ret
- 为什么
constexpr
从初始调用中删除static_strcmp
会导致持续评估失败? - 很明显,即使没有
constexpr
,调用也会在编译时进行评估,那么为什么在第一个版本中char_traits::length
没有相同的行为呢?constexpr
static_strcmp