Virtual Mem Func Ptr Call Fails When Base Class Has No Vtable

Alexandre Oliva
Tue Sep 14 00:03:00 GMT 1999

On Sep 14, 1999, "Martin v. Loewis" <> wrote:

> Without the cast

>    BaseMemCb cb = (BaseMemCb) &Sub::test;

> g++ says (correctly)

> converting `void (Sub::*)()' to `void (Base::*)()' is a contravariance violation

> Please see your C++ book on why this cast is invalid.

Err...  The C++ Standard says [expr.static.cast]:

9 An rvalue of type "pointer to member of D of type cv1 T" can  be  con-
  verted  to  an  rvalue of type "pointer to member of B of type cv2 T",
  where B is a base class (clause _class.derived_)  of  D,  if  a  valid
  standard  conversion  from  "pointer  to  member  of  B  of type T" to
  "pointer to member of D of type T" exists (_conv.mem_), and cv2 is the
  same cv-qualification as, or greater  cv-qualification  than,  cv1.11)
  The  null  member  pointer value (_conv.mem_) is converted to the null
  member pointer value of the destination type.  If class B contains the
  original member, or is a base or derived class of the class containing
  the original member, the resulting pointer to  member  points  to  the
  original  member.   Otherwise,  the  result  of the cast is undefined.
  [Note: although class B need not  contain  the  original  member,  the
  dynamic  type of the object on which the pointer to member is derefer-
  enced must contain the original member; see _expr.mptr.oper_.  ]

Since the class B is a base of the class containing the original
member, the old-style cast should succeed as a static_cast, and should
not invoke undefined behavior.

I seem to recall some wording in the Standard (or some earlier WP)
that would make the *use* of this pointer-to-member undefined unless
it was declared as virtual in the case class, but I can't find it any
more.  Can anybody?  Or was it removed, and the code should work?

Alexandre Oliva IC-Unicamp, Bra[sz]il
oliva@{,guarana.{org,com}} aoliva@{,}
** I may forward mail about projects to mailing lists; please use them

More information about the Gcc-bugs mailing list