Đây có phải là C ++ hợp lệ không?
int main() {
constexpr auto sz = __func__ - __func__;
return sz;
}
GCC và MSVC nghĩ rằng nó ổn, Clang nghĩ rằng nó không phải: Trình biên dịch Explorer .
Tất cả các trình biên dịch đồng ý rằng cái này là OK: Trình biên dịch Explorer .
int main() {
constexpr auto p = __func__;
constexpr auto p2 = p;
constexpr auto sz = p2 - p;
return sz;
}
Clang một lần nữa không thích cái này, nhưng những cái khác thì ổn với nó: Compiler Explorer
int main() {
constexpr auto p = __func__;
constexpr auto p2 = __func__;
constexpr auto sz = p2 - p;
return sz;
}
Có chuyện gì ở đây vậy? Tôi nghĩ số học trên các con trỏ không liên quan là hành vi không xác định nhưng __func__
trả về cùng một con trỏ, không? Tôi không chắc chắn, vì vậy tôi nghĩ rằng tôi có thể kiểm tra nó. Nếu tôi nhớ lại chính xác, std::equal_to
có thể so sánh các con trỏ không liên quan mà không có hành vi không xác định:
#include <functional>
int main() {
constexpr std::equal_to<const char*> eq{};
static_assert(eq(__func__, __func__));
}
Clang nghĩ rằng đó eq(__func__, __func__)
không phải là một biểu thức không đổi, mặc dù std::equal_to::operator()
là constexpr . Các trình biên dịch khác không phàn nàn: Trình biên dịch Explorer
Clang sẽ không biên dịch cái này. Khiếu nại __func__ == __func__
không phải là biểu thức không đổi: Trình biên dịch Explorer
int main() {
static_assert(__func__ == __func__);
}
__func__
và sử dụng biến đó trong static_assert ...
__func__
hoàn toàn khỏi đánh giá constexpr.
__func__
là as-ifstatic const char __func__[] = "function-name";
và tương đương được chấp nhận Demo ...