Initialization of virtual function table pointer

From: DaKoadMunky (dakoadmunky_at_aol.com)
Date: 04/30/04

  • Next message: Peter Hermann: "Re: OOP Language for OS Development"
    Date: 30 Apr 2004 13:20:31 GMT
    
    

    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.


  • Next message: Peter Hermann: "Re: OOP Language for OS Development"

    Relevant Pages

    • Re: initialization of a struct in a vector
      ... >> 'PTStruct' is a POD type. ... >> initialization being applied to all its members. ... But has nothing to do with PTStruct(): ... >> initialization process for POD types does not involve constructors. ...
      (comp.lang.cpp)
    • Re: multiple inheritance and instance data?
      ... If you have a base class, ... having initialization without creation is bad. ...
      (comp.lang.perl.misc)
    • Re: global and static object
      ... C++ global constructors are placed in the same list of ... so the CRT runs those without knowing whether ... it is construction of a C++ object or initialization of a C variable. ... whether those functions call C++ constructors or not. ...
      (microsoft.public.vc.language)
    • Re: Verification of initialization of global objects???
      ... > require the first object to be initialized at the moment when the ... > constructors of the other ones are called. ... > The obvious solution is to remove the body of initialization of the ... > way for a member function to determine whether the global object to ...
      (comp.lang.cpp)
    • Re: C++ virtual function compiler issue
      ... If proper C++ runtime initialization does not occur, ... virtual function is executed, an access violation occurs because the pointer ... >>> (watch it execute in the debugger in disassembly mode), ...
      (microsoft.public.windowsce.platbuilder)