Virtual Mem Func Ptr Call Fails When Base Class Has No Vtable
Tue Sep 14 00:03:00 GMT 1999
On Sep 14, 1999, "Martin v. Loewis" <firstname.lastname@example.org> 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
** I may forward mail about projects to mailing lists; please use them
More information about the Gcc-bugs