gpt4 book ai didi

c++ - __PRETTY_FUNCTION__ 在常量表达式中

转载 作者:可可西里 更新时间:2023-11-01 16:13:43 33 4
gpt4 key购买 nike

请引用这段代码:

#include <type_traits>
#include <string_view>

constexpr std::size_t strlen(char const* s) {
std::size_t n = 0;
while (*s++ != '\0')
++n;
return n;
}

template <std::size_t>
struct X {};

int main() {
constexpr auto pf = __PRETTY_FUNCTION__; // gcc ok; clang ok; (1)
static_assert(std::string_view(__PRETTY_FUNCTION__) == std::string_view("int main()")); // gcc ok; clang ok; (2)
X<strlen(__PRETTY_FUNCTION__)> x; // gcc not ok; clang ok; (3)
}

Clang 8 会编译它,但 GCC 8.3 不会。参见godbolt . GCC 在行 (3) 上失败虽然线(1)(2)没问题。如果我能够申报 pf在线 (1)并使用 __PRETTY_FUNCTION__static_assert这意味着表达式 __PRETTY_FUNCTION__是核心常量表达式。如果我不能申报 X<strlen(__PRETTY_FUNCTION__)> x这意味着 strlen(__PRETTY_FUNCTION__)不是整数常量表达式。

那为什么 strlen(__PRETTY_FUNCTION__)是不是整型常量表达式?是标准暗示的,还是 GCC 错误?

最佳答案

__PRETTY_FUNCTION__ 不是标准的。因此,编译器可以在不同的地方(解析时、构建 AST 时或链接时)实现它。

如果它应该在解析时实现,那么它可以是一个常量表达式(我猜这就是 clang 正在做的事情)。但是,如果它是在链接时实现的(即,编译器为它发出一个符号,链接器将解析它),它就不能是常量表达式。

我认为 GCC 使用后一种情况。

请注意,在这种情况下,您可以采用这些的 sizeof(),因为如果您需要编译时常量字符串的长度计算,它是 const char[]。所以将表达式 3 替换为:

X<sizeof(__PRETTY_FUNCTION__) - 1> x;

它在两个编译器上都能正常编译。

编辑:正如 NathanOliver 指出的那样,GCC 似乎将 __PRETTY_FUNCTION__ 的签名视为 static const char[] 而 clang/visual studio 将其视为 static constexpr const char[].这在 GCC 中是一个令人痛苦的麻烦(不是错误,因为它不是标准的)并且他们似乎已经在 >8.0.0 版本中修复了它。

在表达式 (1) 和表达式 (2) 中,__PRETTY_FUNCTION__ 被衰减为 const char*(指针是常量,但关于数据什么都不能说).对我来说,表达式 (2) 可能无法证明任何事情,因为不能保证等式两边的指针应该相等,即使它们指向“相同”的内容。 string_view 构造函数需要 const char*,因此除 __PRETTY_FUNCTION__ 之外的任何可能衰减为 const char* 的内容都会传递表达式(2).

关于c++ - __PRETTY_FUNCTION__ 在常量表达式中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55850013/

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