Topic: page 233 of the ARM


Author: dcb@slsvitt (David Binderman 3841)
Date: Tue, 19 Jan 93 12:39:11 GMT
Raw View
Hello there,

I've been reading page 233 of the ARM. From what it says, in an constructor,
the vtbl pointer cannot be initialised until the end of the constructor.

I've checked all the compilers I have access to, including a certain
well trusted one from a long time C++ vendor in New Jersey, and they _all_
initialise the vtbl pointer after the calls to any base class
contructors, but before the code of the constructor itself.

Am I right, or are the compilers right ?

I seek your opinion.

Regards

David C Binderman     Dept US/ESI, Bau 60, SEL-Alcatel AG, Lorenz Strasse 10,
D-7000 Stuttgart 40, Germany      dcb@us-es.sel.de   Tel: +49 711 821 3841
   An opinion for every occasion.




Author: steve@taumet.com (Steve Clamage)
Date: Tue, 19 Jan 1993 18:31:56 GMT
Raw View
dcb@slsvitt (David Binderman 3841) writes:

>I've been reading page 233 of the ARM. From what it says, in an constructor,
>the vtbl pointer cannot be initialised until the end of the constructor.

No quite.  Consider this example hierarchy:

 class B {
 public:
     virtual int f();
     int g() { return f(); }
     ...
 };
 class D1 : public B  { ... int f(); ... };
 class D2 : public D1 { ... int f(); ... };

When constructing an object of type D2, the vtable pointer may not
be initialized with the D2 virtual table until the D2 constructor
is entered.  That is, the vtable pointer must not point to the
D2 vtable while the B or D1 constructor is executing.  This is to
ensure that no D2 virtual functions are called before the D2
constructor is entered.

Once the D2 constructor is entered, any virtual function calls must
refer to those of class D2, and so the vtable pointer must be
initialized to the D2 vtable upon entry to the D2 constructor.  When
I say "must", I mean so far as the user program can detect.

If B::B() calls f(), it must mean B::f().
If D1::D1() calls f(), it must mean D1::f().
If D2::D2() calls f(), it must mean D2::f().
It is not necessary to initialize the vtable pointer to accomplish this,
since the compiler can determine statically which function to call.

If B::B() calls g(), g must call B::f();
If D1::D1() calls g(), g must call D1::f();
If D2::D2() calls g(), g must call D2::f();
This is pretty hard to arrange unless the vtable pointer is initialized
upon entry to the constructor.  It also means in general that the
vtable pointer will be re-initialized as each constructor along the
hierarchy is entered.
--

Steve Clamage, TauMetric Corp, steve@taumet.com