【发布时间】:2020-04-18 02:53:23
【问题描述】:
这是有效的 C++ 吗?
int main() {
constexpr auto sz = __func__ - __func__;
return sz;
}
GCC 和 MSVC 认为可以,Clang 认为不行:Compiler Explorer。
所有编译器都同意这个没问题:Compiler Explorer。
int main() {
constexpr auto p = __func__;
constexpr auto p2 = p;
constexpr auto sz = p2 - p;
return sz;
}
clang再次不喜欢这个,但其他人对它没问题:Compiler Explorer
int main() {
constexpr auto p = __func__;
constexpr auto p2 = __func__;
constexpr auto sz = p2 - p;
return sz;
}
这里有什么?我认为在不相关的指针上的算术是未定义的行为,但__func__返回相同的指针,否?我不确定,所以我想我可以测试一下。如果我回忆起来,std::equal_to可以比较无关的指针没有未定义的行为:
#include <functional>
int main() {
constexpr std::equal_to<const char*> eq{};
static_assert(eq(__func__, __func__));
}
clang认为@ 987654337不是一个常量表达式,即使@ 987654338 is constexpr。其他编译器不抱怨:Compiler Explorer
Clang 也不会编译这个。抱怨__func__ == __func__不是常量表达式:Compiler Explorer
int main() {
static_assert(__func__ == __func__);
}
【问题讨论】:
-
来自Function_definition,
__func__就像static const char __func__[] = "function-name";一样被接受Demo... -
有趣的是,如果您使用
__func__初始化一个 constexpr 变量并在 static_assert 中使用它,它就会起作用... -
@Jarod42 所以这是 Clang 中的一个错误?
-
@florestan 喜欢this?它也不会用 Clang 编译。我在问题中的第二个和第三个例子就是你提到的方式。一个编译,另一个不编译。
-
另请参阅 CWG1962,这可能会从 constexpr 评估中完全删除
__func__。
标签: c++ pointers language-lawyer c++17 constexpr