This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: Virtual Mem Func Ptr Call Fails When Base Class Has No Vtable
- To: "Martin v. Loewis" <martin at mira dot isdn dot cs dot tu-berlin dot de>
- Subject: Re: Virtual Mem Func Ptr Call Fails When Base Class Has No Vtable
- From: Alexandre Oliva <oliva at lsd dot ic dot unicamp dot br>
- Date: 14 Sep 1999 04:03:09 -0300
- Cc: andrew dot bell at bigfoot dot com, bug-gcc at gcc dot gnu dot org
- References: <99091108362702.28114@bellfarm> <199909140637.IAA20455@mira.isdn.cs.tu-berlin.de>
On Sep 14, 1999, "Martin v. Loewis" <martin@mira.isdn.cs.tu-berlin.de> wrote:
> Without the cast
> BaseMemCb cb = (BaseMemCb) &Sub::test;
> g++ says (correctly)
> a.cc:21: 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 http://www.dcc.unicamp.br/~oliva IC-Unicamp, Bra[sz]il
oliva@{dcc.unicamp.br,guarana.{org,com}} aoliva@{acm.org,computer.org}
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
** I may forward mail about projects to mailing lists; please use them