奇怪的constexpr typeid错误

时间:2016-09-21 10:38:58

标签: c++ c++11 language-lawyer typeid compiler-bug

给出代码

#include <typeinfo>
#include <type_traits>

struct A {};
struct B {};

static_assert(&typeid(A), ""); // Fine
static_assert(&typeid(B), ""); // Fine
static_assert(&typeid(A) != nullptr, ""); // Fine
static_assert(&typeid(B) != nullptr, ""); // Fine

constexpr auto const * tA = &typeid(A);
constexpr auto const * tB = &typeid(B);
using T = decltype(tA);
using T2 = decltype(tB);
static_assert(std::is_same<T, T2>::value, ""); // Fine, identical types!
static_assert(tA == tA, ""); // Fine (comparing values of identical type)
static_assert(tB == tB, ""); // Fine (comparing values of identical type)
static_assert(tA != tB, ""); // Error: comparing values of identical type
                             //        suddenly not constexpr?

我在Clang中遇到以下错误:

$ clang++ -std=c++1z test.cpp -o test
test.cpp:19:18: error: static_assert expression is not an integral constant expression
static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr?
            ~~~^~~~~
1 error generated.

和海湾合作委员会:

$ g++-6.3.0 -std=c++1z test.cpp -o test
test.cpp:19:1: error: non-constant condition for static assertion
static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr?
^~~~~~~~~~~~~
test.cpp:19:18: error: '(((const std::type_info*)(& _ZTI1A)) != ((const std::type_info*)(& _ZTI1B)))' is not a constant expression
static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr?
            ~~~^~~~~

如果我对voidauto使用tA而不是tB,则无关紧要。只有GCC-s输出略有变化:

$ g++-6.3.0 -std=c++1z test.cpp -o test
test.cpp:19:5: error: non-constant condition for static assertion
    static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr?
    ^~~~~~~~~~~~~
test.cpp:19:22: error: '(((const void*)(& _ZTI1A)) != ((const void*)(& _ZTI1B)))' is not a constant expression
    static_assert(tA != tB, ""); // Error: comparing values of identical type not constexpr?
                ~~~^~~~~

有人可以解释一下为什么只有最后一个static_assert无法编译,而其他人会编译并传递吗?

1 个答案:

答案 0 :(得分:2)

编译器似乎遵守[expr.const]/(2.20)

  

- 关系(5.9)或相等(5.10)运算符,其中未指定结果;

也许指向两个这样的对象的指针不一定被指定为不相等,但它似乎对我来说是个错误。