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