为什么这个函数是在编译时在 g++ 中评估的,而不是在 clang++ 中评估的
Why is this function evaluated at compile time in g++ but not in clang++
我目前正在寻找一种将 class 的名称嵌入到实际对象中的方法。获取名称在运行时不应该花费任何费用。通过使用下面的代码,我在 gcc 中没有额外的成本(因为函数是在编译时评估的)但是由于某种原因 clang 没有在编译时评估代码
我试过使用不同的编译器版本,但据我测试所有版本的 gcc 和所有版本的 clang 产生相同的结果(我无法真正测试 MSVC,因为我找不到必要的标志它不会产生 6000 条装配线)
#include <string>
#include <string_view>
#include <iostream>
template<class T>
constexpr std::string_view get_name()
{
char const* p = __PRETTY_FUNCTION__;
while (*p++ != '=');
for (; *p == ' '; ++p);
char const* p2 = p;
int count = 1;
for (;;++p2)
{
switch (*p2)
{
case '[':
++count;
break;
case ']':
--count;
if (!count)
return {p, std::size_t(p2 - p)};
}
}
return {};
}
int main(){
std::string_view s = get_name<std::string>();
std::cout << s << std::endl;
}
Clang 版本:https://godbolt.org/z/_vY8TD
GCC 版本:https://godbolt.org/z/hhXXWi
我希望 clang 产生与 gcc 类似的结果,但事实并非如此
关键是 get_name()
是一个 constexpr
函数,而你已经写了
std::string_view s = get_name<std::string>();
而不是
constexpr std::string_view s = get_name<std::string>();
在第二种情况下(constexpr
变量的初始化)编译器必须(几乎:忽略as-if规则)初始化s
可变编译时间。
在您的情况下,执行不依赖于 运行 时间已知值,因此编译器有权选择编译时间或 运行 时间执行。
其中一个选择编译时执行,另一个选择运行-时执行。
两种行为都是合法的。
我目前正在寻找一种将 class 的名称嵌入到实际对象中的方法。获取名称在运行时不应该花费任何费用。通过使用下面的代码,我在 gcc 中没有额外的成本(因为函数是在编译时评估的)但是由于某种原因 clang 没有在编译时评估代码
我试过使用不同的编译器版本,但据我测试所有版本的 gcc 和所有版本的 clang 产生相同的结果(我无法真正测试 MSVC,因为我找不到必要的标志它不会产生 6000 条装配线)
#include <string>
#include <string_view>
#include <iostream>
template<class T>
constexpr std::string_view get_name()
{
char const* p = __PRETTY_FUNCTION__;
while (*p++ != '=');
for (; *p == ' '; ++p);
char const* p2 = p;
int count = 1;
for (;;++p2)
{
switch (*p2)
{
case '[':
++count;
break;
case ']':
--count;
if (!count)
return {p, std::size_t(p2 - p)};
}
}
return {};
}
int main(){
std::string_view s = get_name<std::string>();
std::cout << s << std::endl;
}
Clang 版本:https://godbolt.org/z/_vY8TD
GCC 版本:https://godbolt.org/z/hhXXWi
我希望 clang 产生与 gcc 类似的结果,但事实并非如此
关键是 get_name()
是一个 constexpr
函数,而你已经写了
std::string_view s = get_name<std::string>();
而不是
constexpr std::string_view s = get_name<std::string>();
在第二种情况下(constexpr
变量的初始化)编译器必须(几乎:忽略as-if规则)初始化s
可变编译时间。
在您的情况下,执行不依赖于 运行 时间已知值,因此编译器有权选择编译时间或 运行 时间执行。
其中一个选择编译时执行,另一个选择运行-时执行。
两种行为都是合法的。