Thread: Virtual function and multiple inheritance

  1. #16
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Elysia,


    1.

    What did your assembly shows to prove function func_derived is in vtable?

    Quote Originally Posted by Elysia View Post
    I have no idea how it stores the functions the vtables (in case of Derived). They certainly don't show up in the debugger, but they certainly work, so they must be in a vtable. In fact, the assembly shows this.
    Here is my more simplified case to show virtual function is missing in vtable. In class Goo, function myFunc is missing in vtable, but in class Zoo, it is ok to contain virtual function zoo_func.

    2.

    Code:
    #include <iostream>
    
    using namespace std;
    
    class Foo {
    
    	virtual int func1() = 0;
    	virtual int func2() = 0;
    	virtual int func3() {return 0;}
    };
    
    class Goo: Foo {
    public:
    	virtual int func1() {return 0;}
    	virtual int func2() {return 0;}
    	virtual int myFunc() {return 1;}
    };
    
    class Zoo {
    
    public:
    
    	virtual int zoo_func() {return 0;}
    };
    
    int main()
    {
    	Goo g;
    	Zoo z;
    	return 0;
    }

    regards,
    George

  2. #17
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I say it's a limitation of the debugger.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #18
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks CornedBee,


    So you mean in vtable, myFunc is there, but debugger can not display it? If yes, how could we make conclusion that in vtable, myFunc exists?

    Quote Originally Posted by CornedBee View Post
    I say it's a limitation of the debugger.

    regards,
    George

  4. #19
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Yes, exactly. You can make this conclusion from the simple fact that calling the function works.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you can read assembly, it is undeniable proof:
    Code:
    	pD->foo();
    00415020  lea         ecx,[ebp-24h] 
    00415023  call        CMemoryManagerBase<D>::operator-> (4132B7h) 
    00415028  mov         dword ptr [ebp-140h],eax 
    0041502E  mov         eax,dword ptr [ebp-140h] 
    00415034  mov         edx,dword ptr [eax] 
    00415036  mov         esi,esp 
    00415038  mov         ecx,dword ptr [ebp-140h] 
    0041503E  mov         eax,dword ptr [edx] 
    00415040  call        eax  
    00415042  cmp         esi,esp 
    00415044  call        @ILT+1650(__RTC_CheckEsp) (413677h) 
    	pC->foo();
    00415049  lea         ecx,[ebp-40h] 
    0041504C  call        CMemoryManagerBase<C>::operator-> (4138C0h) 
    00415051  mov         dword ptr [ebp-140h],eax 
    00415057  mov         eax,dword ptr [ebp-140h] 
    0041505D  mov         edx,dword ptr [eax] 
    0041505F  mov         esi,esp 
    00415061  mov         ecx,dword ptr [ebp-140h] 
    00415067  mov         eax,dword ptr [edx] 
    00415069  call        eax  
    0041506B  cmp         esi,esp 
    0041506D  call        @ILT+1650(__RTC_CheckEsp) (413677h) 
    	pB->foo();
    00415072  lea         ecx,[ebp-5Ch] 
    00415075  call        CMemoryManagerBase<B>::operator-> (4132EEh) 
    0041507A  mov         dword ptr [ebp-140h],eax 
    00415080  mov         eax,dword ptr [ebp-140h] 
    00415086  mov         edx,dword ptr [eax] 
    00415088  mov         esi,esp 
    0041508A  mov         ecx,dword ptr [ebp-140h] 
    00415090  mov         eax,dword ptr [edx] 
    00415092  call        eax  
    00415094  cmp         esi,esp 
    00415096  call        @ILT+1650(__RTC_CheckEsp) (413677h) 
    	pA->foo();
    0041509B  lea         ecx,[ebp-78h] 
    0041509E  call        CMemoryManagerBase<A>::operator-> (413852h) 
    004150A3  mov         dword ptr [ebp-140h],eax 
    004150A9  mov         eax,dword ptr [ebp-140h] 
    004150AF  mov         edx,dword ptr [eax] 
    004150B1  mov         esi,esp 
    004150B3  mov         ecx,dword ptr [ebp-140h] 
    004150B9  mov         eax,dword ptr [edx] 
    004150BB  call        eax  
    004150BD  cmp         esi,esp 
    004150BF  call        @ILT+1650(__RTC_CheckEsp) (413677h)
    Code:
    	ppnew<D> pD;
    	ppnew<C> pC;
    	ppnew<B> pB;
    	ppnew<A> pA;
    	pD->foo();
    	pC->foo();
    	pB->foo();
    	pA->foo();
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #21
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks CornedBee,


    "Yes, exactly" -- what is your context? You mean in vtable, myFunc is there, but debugger can not display it? If yes, how could we make conclusion that in vtable, myFunc exists?

    Quote Originally Posted by CornedBee View Post
    Yes, exactly. You can make this conclusion from the simple fact that calling the function works.

    regards,
    George

  7. #22
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Elysia,


    We are talking about virtual function in this topic. Which of your function is virtual? And how to find from assembly whether a virtual function is in vtable?

    Quote Originally Posted by Elysia View Post
    If you can read assembly, it is undeniable proof:
    [code] pD->foo();
    00415020 lea ecx,[ebp-24h]
    00415023 call CMemoryManagerBase<D>:perator-> (4132B7h)
    00415028 mov dword ptr [ebp-140h],eax
    0041502E mov eax,dword ptr [ebp-140h]
    00415034 mov edx,dword ptr [eax]
    00415036 mov esi,esp
    00415038 mov ecx,dword ptr [ebp-140h]
    0041503E mov eax,dword ptr [edx]
    00415040 call eax
    00415042 cmp esi,esp
    00415044 call @ILT+1650(__RTC_CheckEsp) (413677h)

    regards,
    George

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    class A
    {
    public:
    	virtual void foo() { }
    };
    
    class B
    {
    public:
    	virtual void foo() { }
    };
    
    class C: public A, public B
    {
    public:
    	virtual void foo() { }
    };
    
    class D: public C
    {
    public:
    	virtual void foo() { }
    };
    Quote Originally Posted by George2 View Post
    Thanks CornedBee,

    "Yes, exactly" -- what is your context? You mean in vtable, myFunc is there, but debugger can not display it? If yes, how could we make conclusion that in vtable, myFunc exists?

    regards,
    George
    CornedBee means that the vtable exists and the functions are part of the vtable but the debugger can't display it. Debugger limitation.
    You can in fact know that it exists in a vtable because it works or by looking at the assembly.
    It doesn't take the address of the function and call it. It actually takes the first 4 bytes and dereferences it to call the appropriate function - undeniable proof that the vtable exists.
    Last edited by Elysia; 02-02-2008 at 09:05 AM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #24
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    http://msdn.microsoft.com/archive/de...angrayhood.asp

    Old article, but still relevant for VC++.

    gg

  10. #25
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    If a class declares a virtual function and you have an instance of that class why would it have to have an entry for that function in the vtable ? There is not much to look up in a table with just one entry so it might just be optimized away.
    Guess that is what you see in your examples. Objects of a class that declare virtual members don't have entries of their ( not yet overridden ) virtual functions in the v-table.
    That is just a guess.
    Kurt

  11. #26
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    But your theory seems wrong. This behavior was seen in debug builds, so the compiler couldn't have optimized it away. Yet. In release, it might just do that.
    In my own tests, I created 4 classes with the same function, all virtual, so that would force the compiler to make a vtable. Yet, only the functions in A and B are shown in the vtable.
    But the assembly shows that the functions do exist in the vtable since it calls a virtual function and, indeed, it calls the right function.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Unless you're writing a compiler you don't need to know how it works, and if you do write a compiler, it'll quickly become blatently obvious why other compilers do things a certain way.

    You shouldn't really be using sizeof on a class that has virtual functions. I'm struggling to find any legitimate reason for needing to know the size of a class with virtual functions.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #28
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Separating allocation and construction? What do you think std::allocator does?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #29
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Thanks Elysia,


    Which exact statements in the assembly language do you mean? Could you quote please?

    "It actually takes the first 4 bytes and dereferences it to call the appropriate function"

    And it is appreciated if you could post you code, and it is good if we could discuss based on the common code base. :-)

    Quote Originally Posted by Elysia View Post
    CornedBee means that the vtable exists and the functions are part of the vtable but the debugger can't display it. Debugger limitation.
    You can in fact know that it exists in a vtable because it works or by looking at the assembly.
    It doesn't take the address of the function and call it. It actually takes the first 4 bytes and dereferences it to call the appropriate function - undeniable proof that the vtable exists.

    regards,
    George

  15. #30
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    No Zuk, you are wrong. :-)


    In my sample, class Zoo has only one method called zoo_func, it is virtual and it is in vtable.

    Quote Originally Posted by ZuK View Post
    If a class declares a virtual function and you have an instance of that class why would it have to have an entry for that function in the vtable ? There is not much to
    look up in a table with just one entry so it might just be optimized away.
    Guess that is what you see in your examples. Objects of a class that declare virtual members don't have entries of their ( not yet overridden ) virtual functions in the v-table.
    That is just a guess.
    Kurt
    Hi CornedBee,

    Quote Originally Posted by CornedBee View Post
    Separating allocation and construction? What do you think std::allocator does?
    I am not sure what do you mean. Does your above reply relates to my question?


    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What is a virtual function pointer?
    By ting in forum C++ Programming
    Replies: 4
    Last Post: 03-05-2008, 02:36 AM
  2. Multiple Inheritance - Size of Classes?
    By Zeusbwr in forum C++ Programming
    Replies: 10
    Last Post: 11-26-2004, 09:04 AM
  3. inheritance and performance
    By kuhnmi in forum C++ Programming
    Replies: 5
    Last Post: 08-04-2004, 12:46 PM
  4. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM
  5. Exporting Object Hierarchies from a DLL
    By andy668 in forum C++ Programming
    Replies: 0
    Last Post: 10-20-2001, 01:26 PM