------- Comment #4 from bangerth at dealii dot org  2006-09-27 04:50 -------
This code can't work. The check() function is not a virtual function,
so calling
  ((&broken)->*func) ();
is translated to
  ( ((Base*)(&broken))->*func) ();
because func is of type 
  void (Base::*) (...)
Then, when you call func, you really mean a function in the derived class,
so a this-pointer adjustment would be necessary, but due to the invalid
cast of &Broken::check this isn't happening. So *this has the wrong value.

The fact that it works in the Works class is simply because Base is the
first base class there, and therefore the this-pointer adjustment does
nothing, so you get lucky.


As for the validity of the testcase, here's a redux:
-------------------
struct B {};
struct D { void f();};

typedef void (B::*BaseFunPtr)();
BaseFunPtr p = (BaseFunPtr)&D::f;
-------------------
Without the C-style cast in the last line, the code is rightfully rejected.
5.4/6 explicitly allows the cast as legal. However, 5.5/3 says that

3 The binary operator ->* binds its second operand, which  shall  be  of
  type  "pointer  to member of T" (where T is a completely-defined class
  type) to its first operand, which shall be of type "pointer to  T"  or
  "pointer  to  a class of which T is an unambiguous and accessible base
  class."  The result is an object or a function of the  type  specified
  by the second operand.

The problem is that the rhs is "pointer to member of Broken", whereas the
left hand side is "pointer to Base", for which Broken is not an unambiguous
and accessible base class (in fact, the opposite statement is true).

The code is therefore invalid and has undefined behavior as per the use of
objects using the wrong type (here a pointer to member of derived that isn't
cast back to its real type).

W.


-- 

bangerth at dealii dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bangerth at dealii dot org
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29243

Reply via email to