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.