http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50282
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution| |INVALID --- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-09-05 08:08:08 UTC --- (In reply to comment #6) > I guess we have some agreement on HOW gcc works. the following are what i got > through the test-cases: > 1.simply using &T4::f, will only get a value of T2::f, as the function f > accessed through T4,is actually defined in T2. NO CONVERSION WILL TAKE PLACE. > 2.directly assign &T4::f to an object of type void(T4::*)(void), will > IMPLICITELY cause an conversion from void(T2::*)(void) to void (T4::*)(void), Yes, the point is that implicit conversion is safe, and done correctly by the compiler, which knows what it is doing. Your uses of reinterpret_cast were not all safe, and lie to the compiler - you should always be very careful when using reinterpret_cast. > That means: > If I want to store a pointer-to-member-function, i should use its original > type, as T2::* ,or T4::T2::* which is only verbose but makes no difference in > current g++ implementation), in the case, and that's what i usually have to > have done in my programs (but not in the test-cases). You can make use of the implicit conversion to void(T4::*)() BEFORE you cast to void(N::*)(), and then it is safe to cast BACK to void(T4::*)(). That's what your TestCase2 does. That implicitly converts from P1 to P2 which is safe, then you use reinterpret_cast to go from P2 to P3 and back to P2, which is OK What you cannot do is reinterpret_cast from P1 to P3 to P2 and expect the right result, because you have not cast back to the original type. > So, I can accepte the way gcc implements the conversions, for I just tested > several cases and i can find out which way I can follow. But I have some > suggestions: > > For the compiler always knows from the codes that f is accessable through T4, > we can have two forms of assign &T4::f to objects of type T4::*, > 1. (void)(T4::*pf4)() = &T4::T2::f, or > 2, (void)(T4::*pf4)() = static_cast<void (T4::*)()>(&T2::f) ; > and: > 3 (void)(T4::*pf4)() = &T2::f, will yield an warning. > > I thinks this will make programmers feel easier and happier. Did you mean &T4::f in the third case? If not, it wouldn't make me happier, it's obvious that there is an implicit conversion, because the declarator says "T4" and the initializer says "T2" Closing this as invalid, if you want an enhancement for a new warning please file a separate request with a clear explanation of what you want.