The following source generates warning C4407 in VC and the compiler does indeed produce the incorrect code.
struct A1 {
int a1;
};
struct A2 {
int a2;
};
struct B: A1, A2 {
void f() {
std::cout << this << '\n';
}
};
int main() {
B b = B();
void (B::*pb)() = &B::f;
void (A2::*pa)() = (void (A2::*)())pb; // performs static_cast actually
std::cout << (std::uintptr_t&)pb << '\n';
std::cout << (std::uintptr_t&)pa << '\n';
B* pB = &b;
A2* pA = pB;
std::cout << pB << '\n';
std::cout << pA << '\n';
(pB->*pb)();
(pA->*pa)();
}
The code produced is incorrect because pointer pA
is not adjusted when invoking pa
, leading to a wrong this
pointer value in f
. However, the code compiles fine in GCC and clang without any warning (except for the strict-aliasing one). Pointer pA
is properly adjusted in the code produced by GCC and clang. So, I'm wondering what does the standard say about this? Is the cast in the above code fine according to the standard? Or is it a non-standard extension of GCC and clang?