12

I came across a problem with g++ with upcasting of a member pointer in a constexpr context using static_cast. See code example.

When compiling with g++ version 6.3 and 7.0 they give a compilation error saying reinterpret_cast is not a constant expression. While clang version 4.0 gives no error, which I think is correct since there is no reinterpret_cast here.

Is this a bug in g++ or clang? What is the correct behavior?

struct Base {}; struct Derived : Base { int i; }; struct Ptr { constexpr Ptr(int Derived::* p) : p(static_cast<int Base::*>(p)){} int Base::* p; }; constexpr Ptr constexpr_ptr(&Derived::i); 

Compiler output

g++ -c -std=c++14 test.cpp test.cpp:17:40: in constexpr expansion of ‘Ptr(&Derived::i)’ test.cpp:11:41: error: a reinterpret_cast is not a constant expression constexpr Ptr(int Derived::* p) : p(static_cast<int Base::*>(p)){} ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 
1
  • 1
    This is not really an upcast. Commented Oct 19, 2017 at 10:50

1 Answer 1

3

GCC presumably misapprehends [expr.static.cast]/12, which permits your cast and notes that

If class B contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member. Otherwise, the behavior is undefined.

Since Base is indeed a base of the class containing the member, the behaviour should be defined, and the constructor call a constant expression.

Sign up to request clarification or add additional context in comments.

1 Comment

Workaround, or what gcc version is this fixed in?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.