none
Missing virtual function entry in vtable

    Question

  • Hi
    I have a class like this.

    class B
    {
    public:
    	B()
    	{
    		b = 0;
    	}
    	virtual void Print()
    	{
    	   cout<<" b = "<<b<<endl;
    	}
    
    protected:
    	      int b;
    	   
    };
    
    class C : public B
    {
    public:
    	   C()
    	   {
    		   c = 100;
    	   }
    	   virtual void Print()
    	   {
    			cout<<" c = "<<c<<endl;
    	   }
    	   virtual void Display()
    	   {
    			cout<<" My display func......"<<endl;
    	   }	  
      
    private:
    	    int c;
    };
    
    void main()
    {
    	C obj;
    	C* CPtr = &obj;
    	CPtr->Print();
    }
    
    
    But when i exploded the obj, i'm not able to find the entry for the virtual function Display in vtable. Will the obj will have 2 vfptrs?
    One pointing the vtable inherited from class B, and other one pointing to the vtable of its own?
    Where is the entry for the Display?

    The layout looks like this:

    obj -------------------------  0x0013ff74
       B
          _vfptr -----------------  0x0042801c
                [0] ---------------   0x0040102d  C::Print(void)
          b ----------------------   0
       c -------------------------   100

    I know the address of obj::B and the address of obj::B::_vfptr are 0x0013ff74.
    But i couldnt find the display? Can somebody help me



                   
    Friday, January 08, 2010 5:59 AM

Answers

  • If you define a helper variable:

     

        void (**vt)() = *(void (***)())&obj;

     

    then you can type in Watch window this expression:

     

        vt,2

    • Marked as answer by Wesley Yao Thursday, January 14, 2010 3:37 AM
    Friday, January 08, 2010 10:23 AM
  • Syed Babu wrote:
    > class B
    > {
    > public:
    >  B()
    >  {
    >   b = 0;
    >  }
    >  virtual void Print()
    >  {
    >     cout<<" b = "<<b<<endl;
    >  }
    >
    > protected:
    >        int b;
    >
    > };
    >
    > class C : public B
    > {
    > public:
    >     C()
    >     {
    >      c = 100;
    >     }
    >     virtual void Print()
    >     {
    >    cout<<" c = "<<c<<endl;
    >     }
    >     virtual void Display()
    >     {
    >    cout<<" My display func......"<<endl;
    >     }
    >
    > private:
    >      int c;
    > };
    >
    > void main()
    > {
    >  C obj;
    >  C* CPtr = &obj;
    >  CPtr->Print();
    > }
    >
    >
    > But when i exploded the obj, i'm not able to find the entry for the virtual function Display in vtable. Will the obj will have 2
    > vfptrs?
     
    There's one vtable with two entries, but the debugger only shows one. It's the debugger's fault.
     
    The compiler reuses B::_vfptr to store a pointer to C's vtable (which also works as a B's vtable, being a superset of it). The debugger is not smart enough to see through this sleigh of hand.
    --
    Igor Tandetnik
    • Marked as answer by Wesley Yao Thursday, January 14, 2010 3:37 AM
    Friday, January 08, 2010 12:56 PM

All replies

  • Maybe because C is not derived further.
    Microsoft MVP - Visual C++
    Blog: http://nibuthomas.com
    Posts are provided as is without warranties or guaranties.
    Friday, January 08, 2010 9:38 AM
  • class A
    {
    public:
    	   A()
    	   {
    		   a = 0;
    	   }
    	   virtual void Print()
    	   {
    		   cout<<" Value = "<<a<<endl;
    	   }
    private:
    	    int a;
    };
    void main()
    {
    	A obj;
    }
    I dont think so....If that is the case, in the above code also i should not get the vfptr for obj, because A is not derived further .
    But it gives the layout like this:

    obj ---------------------  0x0013ff78
       _vfptr ---------------  0x0013ff78
            [0] --------------- 0x0040102d A::Print(void)
       a --------------------- 0
    Friday, January 08, 2010 9:58 AM
  • If you define a helper variable:

     

        void (**vt)() = *(void (***)())&obj;

     

    then you can type in Watch window this expression:

     

        vt,2

    • Marked as answer by Wesley Yao Thursday, January 14, 2010 3:37 AM
    Friday, January 08, 2010 10:23 AM
  • If we add Display to B the debugger shows it.
    Microsoft MVP - Visual C++
    Blog: http://nibuthomas.com
    Posts are provided as is without warranties or guaranties.
    Friday, January 08, 2010 10:26 AM
  • Thanks viroel
    Now I'm able to see the function pointer for Display.

    But why should I do void (**vt)() = *(void (***)())&obj;

    Correct me if I'm wrong. You are trying to get addrss of obj in the vt poitner right....
    But If I do void* vt = (void*)&obj;
    It is not showing
    Friday, January 08, 2010 10:32 AM
  • Srry its not the address of obj...
    its the address of vtable right
    Friday, January 08, 2010 10:41 AM
  • Syed Babu wrote:
    > class B
    > {
    > public:
    >  B()
    >  {
    >   b = 0;
    >  }
    >  virtual void Print()
    >  {
    >     cout<<" b = "<<b<<endl;
    >  }
    >
    > protected:
    >        int b;
    >
    > };
    >
    > class C : public B
    > {
    > public:
    >     C()
    >     {
    >      c = 100;
    >     }
    >     virtual void Print()
    >     {
    >    cout<<" c = "<<c<<endl;
    >     }
    >     virtual void Display()
    >     {
    >    cout<<" My display func......"<<endl;
    >     }
    >
    > private:
    >      int c;
    > };
    >
    > void main()
    > {
    >  C obj;
    >  C* CPtr = &obj;
    >  CPtr->Print();
    > }
    >
    >
    > But when i exploded the obj, i'm not able to find the entry for the virtual function Display in vtable. Will the obj will have 2
    > vfptrs?
     
    There's one vtable with two entries, but the debugger only shows one. It's the debugger's fault.
     
    The compiler reuses B::_vfptr to store a pointer to C's vtable (which also works as a B's vtable, being a superset of it). The debugger is not smart enough to see through this sleigh of hand.
    --
    Igor Tandetnik
    • Marked as answer by Wesley Yao Thursday, January 14, 2010 3:37 AM
    Friday, January 08, 2010 12:56 PM