http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50282
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-09-04 18:45:24 UTC --- The problem is is your code, not gcc The type of &T4::f is void(T2::*)() not void(T4::*)() so when you cast the pointer to void(T4::*)() you are not casting back to the original type. You can fix the code by using reinterpret_cast<void(T2::*)()> for the cases that use the expression &T4::f, instead of reinterpret_cast<void(T4::*)()> For what it's worth, clang gives exactly the same result as g++ for a reduced version of your program: // define class N with no member, // we just need a type void(N::*)() of which an object can hold a pointer-to-member-function class N {} ; // define class T1 & T3 with some member data/functions // so that an object of class T4 which derives from T1 & T2 & T3 // will has its base object of type T2 have different address from the object itself. class T1 { public: char c ; int i ; } ; class T3:virtual public T1 { public: int i3 ; public: virtual void f2() { __builtin_printf("Foo3 !! this=%p\n", (void*)this); } ; } ; // define class T2 // T2 has a memmber function f, which our pointer-to-member-function will point to. // as T4 derives from T2 as a public base type, this function is an accessable from T4 ; // the function outputs the value of 'this' pointer, which i expect it always points to an object of T2. class T2 { public: int i2 ; public: virtual void f() { __builtin_printf("Foo2 !! this=%p\n", (void*)this); } ; } ; // define class T4, which simply derives from T1&T2&T3 class T4:public virtual T1, public T3, public T2 {} ; int main(int, char**) { T4 t4 ; void (N::*pfn)() = 0; void(T4::*pf4)() = &T4::f ; // this line shows the address of t4 and its base object t4.t2 differ ; __builtin_printf("AddressOf t4=%p, t4.t2=%p\n", (void*)(&t4), (void*)(&(T2&)(t4))); { __builtin_printf("\nwhat i expect:\n"); // the following lines show what i expect to see: // no matter what form the function call is, the function tells me the address of t4.t2 t4.f() ; (t4.*(&T4::f))() ; (t4.*pf4)() ; } { __builtin_printf("\nTestCase1:\n"); __builtin_printf("pfn assignment: pfn = reinterpret_cast<void(N::*)()>(&T4::f) \n"); __builtin_printf("Function call form: (t4.*reinterpret_cast<void(T4::*)()>( pfn )() \n"); // Case1: // pfn is assigned directly from &T4::f, // but actually, its value shows that is &T2::f pfn= reinterpret_cast<void(N::*)()>(&T4::f) ; // comparing with the result i memtioned above, this is not what i want. (t4.*reinterpret_cast<void(T4::*)()>(pfn))() ; } { __builtin_printf("\nTestCase2:\n"); __builtin_printf( "pfn assignment: pfn = reinterpret_cast<void(N::*)()>(pf4) \n"); __builtin_printf("Function call form: (t4.*reinterpret_cast<void(T4::*)()>( pfn )() \n"); // Case2: pfn is transfromed from pf4, which is defined as type void(T4::*)(), and its value // has been correctly assigned as &T4::f, not &T2::f pfn = reinterpret_cast<void(N::*)()>(pf4) ; // this time, the function call works correctly (t4.*reinterpret_cast<void(T4::*)()>(pfn))() ; } { __builtin_printf("\nTestCase3:\n"); // Case3: // this case exactly follows the standered draft, if anyone might say // in the above casese i used a lvalue(pfn), // this time, i have rvalue only, but it's obviously not functioning. __builtin_printf("Function call form: (t4.*reinterpret_cast<void(T4::*)()>( reinterpret_cast<void(N::*)()>(&T4::f)))() \n"); (t4.*reinterpret_cast<void(T4::*)()>( reinterpret_cast<void(N::*)()>(&T4::f) ))() ; } } When the 1st and 3rd tests are altered to use reinterpret_cast<void(T2::*)()> it gives the results you expect so I think this is invalid