reinterpret_cast of pointer-to-member

Hi everyone,
I am working on a patch that involves reinterpret_cast of pointer to member. Working on Godbolt, it seems that the casts don’t always make sense. Take a look at https://godbolt.org/z/6E7aoK.
Both c and cs are supposed to point to the same field. However, c has the wrong offset (12) while cs has the right offset (0). This can be seen from the return value also (returns 16 instead of the expected 29).
So my query is: are reinterpret_cast on pointer-to-member considered undefined behaviour? Because different optimisation levels give different answers (try -O2).
Warm regards,
Deep

Hi Deep, I'm not a language lawyer, but I believe it is as you suspect:

The result of this conversion is unspecified, except in the following cases: [...]
(10.2) Converting a prvalue of type “pointer to data member of X of type T1” to the type “pointer to data member of Y of type T2” (where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer-to-member value.

(https://timsong-cpp.github.io/cppwp/n4861/expr.reinterpret.cast#10)

I would interpret that as: the cast expression is legal code, but using the result with the pointer-to-member-access operators is undefined behavior unless you reinterpret_cast them back to the original type first.

My take on this is that this language feature allows you to do type erasure on a pointer-to-member as long as you know the original type at the client site.

Best
Tobias

Ableton AG, Schoenhauser Allee 6-7, 10119 Berlin, Germany
Sitz (Registered Office) Berlin, Amtsgericht Berlin-Charlottenburg, HRB 72838
Vorstand (Management Board): Gerhard Behles, Jan Bohl
Vorsitzender des Aufsichtsrats (Chair of the Supervisory Board): Uwe Struck