jotik
jotik

Reputation: 17910

Weird constexpr typeid errors

Given the code

#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?

I get the following error with 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.

And GCC:

$ 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?
            ~~~^~~~~

It doesn't matter if I use void instead of auto for tA and tB. Only GCC-s output changes slightly:

$ 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?
                ~~~^~~~~

Can someone please explain why only the last static_assert fails to compile, whereas the others do compile AND pass?

Upvotes: 3

Views: 768

Answers (1)

Columbo
Columbo

Reputation: 60999

The compilers seem to adhere to [expr.const]/(2.20):

— a relational (5.9) or equality (5.10) operator where the result is unspecified;

Perhaps pointers to two such objects are not necessarily specified to be unequal, but it appears to be a bug to me, nonetheless.

Upvotes: 2

Related Questions