Topic: Triggering the dynamic binding mechanism without invocation
Author: jamshid@emx.cc.utexas.edu (Jamshid Afshar)
Date: 14 Jun 1993 16:33:33 -0500 Raw View
In article <1176@clbull.frcl.bull.fr> freja@mip3035.Berkeley.EDU (Etienne
Frejaville) writes in rather long lines:
>struct A { virtual void f() {} };
>struct B : A { virtual void f() {} };
>main () {
> A a, *pa;
> B b;
> typedef void (A::*PF)(); // (1)
> pa=&b; // (2)
> PF pf = pa->f; // (3)
> pa=&a; // (4)
> (pa->*pf)(); // (5)
>}
>Lines (2) and (3) store in pf the adress of f of B. Line (4) won't prevent
>line (5) to invoke effectively f of B.
Line (3) is a syntax error. You must *always* use the syntax
`&Class::FuncName' to get a member function pointer.
PF pf = &A::f; // correct
With this fix the code should compile and run correctly -- line (5)
calls A::f(). Apparently gcc (I'm using 2.4.3) allows your syntax:
Object* obj = new Object;
void (Object::*mfp) = obj->foo; // error, but gcc allows
as either an extension to C++ or because it's a bug in the compiler.
Gcc does warn that "ANSI C++ forbids implicit conversion from void*"
so maybe it converts `o->foo' to a `void*' which the points to the
location of the actual member function `foo' that would be called for
`obj'? Interesting extension, but why use a `void*' instead of a
function pointer? And what's the correct syntax for calling the
function? For example, some compilers use special calling conventions
for member functions that aren't used for regular functions.
>Is this behaviour normal. And above all, is it standard ?
Your code is not (and most likely never will be) correct C++. You
might ask in gnu.g++.help if the above is an extension or bug.
Another important thing to remember about member function pointers is
that converting (implicitly or with a cast) one type of member
function pointer to another type is undefined. I don't think a
compiler is required to even compile such a conversion. I know
compilers are not required to accept a conversion of a member function
pointer to a `void*' or to a regular function pointer.
Jamshid Afshar
jamshid@emx.utexas.edu
Author: freja@mip3035.Berkeley.EDU (Etienne Frejaville)
Date: 7 Jun 93 09:02:28 GMT Raw View
I have noticed that (at least with GNU C++) it is possible to trigger the dynamic binding mechanism on a
function without invoking it. Indeed, when considering the following program :
class A {
public :
virtual void f() {}
};
class B : public A {
public :
void f() {}
};
main () {
A a, *pa;
B b;
typedef void (A::*PF)(); // (1)
pa=&b; // (2)
PF pf = pa->f; // (3)
pa=&a; // (4)
(pa->*pf)(); // (5)
}
Lines (2) and (3) store in pf the adress of f of B. Line (4) won't prevent line (5) to invoke effectively f of B.
Is this behaviour normal. And above all, is it standard ?
Thanks in advance.
--
--------Etienne FREJAVILLE---Bull S.A -------------------------------------
SPO-PARIS/DSE/LPS/TOPAS e-mail: E.Frejaville@frcl.bull.fr
Rue Jean-Jaures, F6/1D/05, BP 53 tel: (33-1) 30806548
78340 Les Clayes-sous-Bois, France Fax: (33-1) 30807950