Initialization of virtual function table pointer

D

DaKoadMunky

I was recently looking at some assembly code generated by my compiler. When
examining the assembly code associated with constructors I noticed that the
dynamic-dispatch mechanism was enabled before member initialization but after
base initialization.

To speak in implementation details the virtual function table pointer for
objects being constructed was set before member initialization but after base
initialization.

Curiousity then led me to the following toy program...

<CODE>

struct Base
{
Base(int) {}
};

class Derived : public Base
{
public:

Derived():
Base(ProxyForVirtualFunction()),
member(ProxyForVirtualFunction())
{
}

private:

int ProxyForVirtualFunction()
{
return VirtualFunction();
}

virtual int VirtualFunction()
{
return 0;
}

int member;
};

int main()
{
Derived();

return 0;
}

</CODE>

In the example code class "Derived" has a base class "Base" which must be
initialized with an integer. It also has an int member that is to be
initialized. In both cases the value used for initialization is produced by
indirectly calling a virtual function. The reason for the indirect call is
because my compiler optimizes away direct calls to virtual functions within
constructors.

The call sequence that produces the value to be used as the base class
initializer results in a program crash because the virtual function table
pointer has not yet been set. The attempt to dispatch the virtual function
call accesses an out-of-bounds memory location and all hell breaks loose.

The call sequence that produces the value to be used as the member initializer
results in no fault because at that point the virtual function table pointer
has been set.

I am wondering if the C++ language standard states when a dynamic dispatch
mechanism is expected to be associated with an object under construction and
what assurances the language standard makes regarding when it is okay to assume
that dynamic dispatch is safe.

Any insight would be appreciated.
 
J

Janusz Szpilewski

DaKoadMunky said:
I am wondering if the C++ language standard states when a dynamic dispatch
mechanism is expected to be associated with an object under construction and
what assurances the language standard makes regarding when it is okay to assume
that dynamic dispatch is safe.

Any insight would be appreciated.

All member functions called from constructor are statically linked what
implies that dynamic dispatch is not used in that case. It is easy to
imagine the disastrous effect when an overriding function tried to
access a member that was not initialized yet.

For more information check:

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.3
 
D

DaKoadMunky

All member functions called from constructor are statically linked

I am aware of that. That is why my example called the virtual functions
indirectly through a non-constructor function where such calls would not be
statically linked.
It is easy to imagine the disastrous effect when an overriding function tried to
access a member that was not initialized yet.

Yes it is. In fact I have been studying Java recently and was surprised to
discover that in that language derived class overrides are invoked when called
from base class constructors. After thinking about it though I am of the
opinion that can be a useful feature if the appropriate cautions are taken and
the author of the base class documents that a dynamically dispatched method is
being called from a base class constructor. I guess that is an argument for
another time though.


Brian F. Seaberg
Naperville, Illinois
Delray Beach, Florida
 
J

Janusz Szpilewski

DaKoadMunky said:
Yes it is. In fact I have been studying Java recently and was surprised to
discover that in that language derived class overrides are invoked when called
from base class constructors.


In Java all data members are zero initialized before any contructor code
gets called. It is also up to the programmer to specify if a base class
constructor should be called. So there is more control and no risk of
using an unitialized data member. At least not bigger than using one
with a dummy value. So potentially confusing object construction rules
applied in C++ do not have to be reflected in Java.
 
J

JKop

Janusz Szpilewski posted:
In Java all data members are zero initialized before any contructor
code gets called.


Better to have the choice.
It is also up to the programmer to specify if a base
class constructor should be called. So there is more control and no
risk of using an unitialized data member. At least not bigger than
using one with a dummy value. So potentially confusing object
construction rules applied in C++ do not have to be reflected in Java.


I agree that dumbing down _can_ make it easier for people who aren't
professional. But then you have professional programmers, who don't want to
work with a Virtual Machine, reminiscent of Visual Basic.

And if a Derived class does _not_ call the constructor of the Base class,
then you can't really say that it's a derived class at all. Is a dog a
mammal if it hasn't even been conceived, born, breast-fed, weined... I don't
think so.

-JKop
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top