Thread: Pure Virtual Function - Virtual Method Table

  1. #1
    Registered User
    Join Date
    Jun 2008
    Posts
    8

    Pure Virtual Function - Virtual Method Table

    Hi C++ Coders,
    Can you please help me regarding one thing.
    For pure virtual function, what are the entries created in the virtual method table.
    Say I have a program:
    Code:
    class base
    {
       public:
                virtual void display() = 0;
             ...........
    };
    
    class derived1:public base
    {
      public:
               void display()
                {
                   cout<<"Derived1:";
                }
    };
    
    class derived2:public derived
    {
      public:
               void display()
                {
                   cout<<"Derived2:";
                }
    };
    So here when derived class functions will be called through base class pointer, then how with the help of virtual method table the proper function is calling?
    And what are the entries in the 3 vtable for these 3 classes?

    And one more query:
    To see vtable core dump, is there any compiler flag (g++) in Solaris / Red Hat Linux to be used?

    Thanks in advance.

    With regards,
    u_peerless

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The basic logic is simple.
    In derived2, the vtable points towards derived2::display.
    In derived1, the vtable points towards derived1::display.
    In base, the vtable points towards base::display.
    So the compiler just calls the correct function entry in the vtable and the correct function is called.
    However, note that it may not be like this - the implementation may be done differently. Just know that it works and leave it at that.
    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.

  3. #3
    Registered User
    Join Date
    Jun 2008
    Posts
    8
    ya that is the behavior of Virtual functions. But I want to know the internally how the vtable is being created to do like this. I know "this happens". But do not know "why happens". So I want to know in that perspective, how the internally vtable is created and what are the entries for that?

    For pure virtual function, we cant create instance of base class, so base::display is not possible here. But if we do not declare pure virtual function, then it will be called by a base class pointer. So I suppose for "not pure virtual function" and "pure virtual function", the entries for vtable for base class should differ in these two cases. So what is this difference?

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    As I say, it's implementation defined. All implementations are not required to do it in the same way, as long as it works, but one possible and very plausible explanation is that the vtable is static and is created by the constructor.
    In dervied2's constructor, for example, the vtable is created and the function entry is set to point to derived2::display. What that entry looks like is also implementation defined, so again, it's difficult to speculate. They may just be numbered. The compiler can number each function starting from 0 and add n * sizeof(ptr) offset to the vtable to find the function to call.
    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.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by u_peerless View Post
    ya that is the behavior of Virtual functions. But I want to know the internally how the vtable is being created to do like this. I know "this happens". But do not know "why happens". So I want to know in that perspective, how the internally vtable is created and what are the entries for that?
    "V-tables" are not specified by the standard, and in fact don't even have to be used. Whatever knowledge you gain will be compiler specific, most likely. That's fine if that's what you're looking for, just know that it doesn't have anything to do with ISO C++.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    As medievalelks says, implementation is the implementation's business.

    That said, there are several things to notice here:

    First, the =0 syntax for marking a function pure was probably derived from the idea of simply putting the null pointer in the vtable at that point.

    Second, modern compilers put a small stub function there that emits a "Pure function called" error message and then aborts the application. To see this, you can run this (erroneous) program:
    Code:
    class Base
    {
      void init() { do_virtual(); }
    public:
      Base() { init(); }
      virtual void do_virtual() = 0;
      virtual ~Base() {}
    };
    
    class Derived
    {
    public:
      virtual void do_virtual() {}
    };
    
    int main()
    {
      Derived d;
    }
    Compile without optimizations, or the compiler might optimize the entire call graph away.

    Third, there's no particular reason why a vtable should be generated for an abstract class at all. Or at least I can't think of one.
    Last edited by CornedBee; 06-07-2008 at 01:16 AM.
    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

  7. #7
    Registered User
    Join Date
    Jun 2008
    Posts
    8
    Thanks all for your reply. Finally I got the idea behind this.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    There is absolutely no requirement in the standard that a class with a pure virtual function have ANY virtual function table.

    The requirement comes down to the "function actually called in response to object->VirtualMember() is determined by the actual type of object".

    A virtual function table is ONE WAY of meeting this requirement. Another way would be this sort of logic in (pseudo-code) -- which is actually a more literal interpretation of how the standard describes the requirement;
    Code:
       if (object is of type_A)
              object->type_A::VirtualMember();
       else if (object is of type_B)
              object->type_B::VirtualMember();
       // etc
    A virtual function table is the way this requirement is met by most real-world compilers, because the overhead is considered acceptable (memory overhead is a set of virtual tables per object, performance overhead once class is instantiated is fixed at runtime to retrieving function pointer from said tables, setting up argument list, and then dereferencing the function pointer).

    One downside of virtual function tables is that they become quite complex in multiple-inheritance situations (typically classes with multiple bases require multiple vtables, and it is necessary to manage relationships between them). This is one reason (among several) that a lot of popular languages do not support multiple inheritance.

    Quote Originally Posted by CornedBee View Post
    First, the =0 syntax for marking a function pure was probably derived from the idea of simply putting the null pointer in the vtable at that point.
    Not even remotely true.

    The =0 syntax for pure virtual functions has nothing to do with the vtables. It is a signal to the compiler that the class should not be instantiated, and that derived classes also should not be instantiated unless they define a non-pure version of the same member function. There was some discussion by the standards committee about introducing a new keyword (eg "pure") to cover the same circumstance, but the "=0" syntax stuck.

    There is no need to put a zero entry into a vtable for pure member functions, because a class that is not instantiated, by definition, does not need a vtable -- the vtable is populated when constructing the DERIVED class. Since code that attempts to instantiate an abstract class is required to trigger a COMPILATION error, an entry in a vtable (a RUN TIME entity) is not required.

    Quote Originally Posted by CornedBee View Post
    Second, modern compilers put a small stub function there that emits a "Pure function called" error message and then aborts the application.
    <code elided>
    Compile without optimizations, or the compiler might optimize the entire call graph away.
    The code you describe here (when minor typos are fixed; you left out a "()") exhibits undefined behaviour (calling a pure virtual function in a constructor, or in a function called by a constructor), so any discussion of what "modern" compilers, or any other compilers, do with it is irrelevant.
    Quote Originally Posted by CornedBee View Post
    Third, there's no particular reason why a vtable should be generated for an abstract class at all. Or at least I can't think of one.
    I won't debate with that one

    Assuming that your compiler works with vtables ...... vtables are typically generated at run time when a class is instantiated. However, code that uses an abstract class (eg abstraction->VirtualMember()) forces the compiler to employ explicit assumptions about the layout and content of the vtable(s).
    Last edited by grumpy; 06-06-2008 at 06:02 PM. Reason: Remove excessive quoting of code

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Not even remotely true.

    The =0 syntax for pure virtual functions has nothing to do with the vtables. It is a signal to the compiler that the class should not be instantiated, and that derived classes also should not be instantiated unless they define a non-pure version of the same member function. There was some discussion by the standards committee about introducing a new keyword (eg "pure") to cover the same circumstance, but the "=0" syntax stuck.

    There is no need to put a zero entry into a vtable for pure member functions, because a class that is not instantiated, by definition, does not need a vtable -- the vtable is populated when constructing the DERIVED class. Since code that attempts to instantiate an abstract class is required to trigger a COMPILATION error, an entry in a vtable (a RUN TIME entity) is not required.
    What has the actual requirement to do with the origin of the syntax? What I said is true - Bjarne Stroustrup explicitly says so in "The Design and Evolution of C++".

    And peculiarly enough, compilers often do generate vtables for abstract classes.

    The code you describe here exhibits undefined behaviour, so any discussion of what "modern" compilers, or any other compilers, do with it is irrelevant.
    I mentioned that the code is erroneous, and I didn't mean the missing () (fixed in the post now). However, experimental data on what the compilers actually can still be interesting in that it shows an implementation detail of those compilers.

    vtables are typically generated at run time when a class is instantiated.
    Huh? No, they're not. They're statically written into the executable. They're bound when the class is instantiated.
    Last edited by CornedBee; 06-07-2008 at 01:21 AM.
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Calling a pure virtual function from a constructor...
    By starcatcher in forum C++ Programming
    Replies: 4
    Last Post: 02-10-2009, 09:12 AM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. virtual or pure virtual
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 12-01-2001, 07:19 PM