When is VTable in C++ created?
Asked Answered
A

2

13

I would like to know when is a vtable created? Whether its in the startup code before main() or is it at some other point of time??

Alane answered 3/10, 2010 at 11:8 Comment(0)
S
15

A vtable isn't a C++ concept so if they are used and when they are created if they are used will depend on the implementation.

Typically, vtables are structures created at compile time (because they can be determined at compile time). When objects of a particular type are created at runtime they will have a vptr which will be initialized to point at a static vtable at construction time.

Sherronsherry answered 3/10, 2010 at 11:12 Comment(5)
Thanks, But one of my instructors told me that a vtable is created before calling the main function. It is created during the StartupCRT code. I just wanted to confirm that and understand more about it.Alane
@Sen: Perhaps, but perhaps not. A C++ implementation doesn't have to use vtables so whether they embedded in the binary, constructed in startup code or dynamically allocated when needed (unlikely) is entirely up to the implementation. Whatever the implementation chooses to do should be transparent to the program so it should be much more important that a programmer knows what behaviour to expect from the use of virtual functions than how they are implemented on the particular platform that he is using.Sherronsherry
@Sen: StartupCRT sounds a lot like a Microsoft-specific thing, and what he or she told you may well be true for Microsoft's Visual C++, but as Charles says the C++ Standard itself lets each compiler vendor choose whatever implementation they like as long as it performs properly. Other vendors probably won't even have a "StartupCRT" function.Groats
@user433534: Ya, you are right.. we were having a training and we were using Microsoft Visual C++ 2010..Alane
@Sen: it helps if you also tag your questions with vc++ then. And technically I don't think it's true, either. I believe they're created during program loading, whereas the CRT is initialized after loading but before main.Lineage
E
4

The vtable is created at compile time. When a new object is created during run time, the hidden vtable pointer is set to point to the vtable.

Keep in mind, though, that you can't make reliable use if the virtual functions until the object is fully constructed. (No calling virtual functions in the constructor.)

EDIT I thought I'd address the questions in the comments.

As has been pointed out, the exact details of how the vtable is created and used is left up to the implementation. The c++ specification only provides specific behaviors that must be guaranteed, so there's plenty of wiggle room for the implementation. It doesn't have to use vtables at all (though most do). Generally, you don't need to know those details. You just need to know that when you call a virtual function, it do what you expect regardless of how it does it.

That said, I'll clarify a couple points about a typical implementation. A class with virtual functions has a hidden pointer (we'll call vptr) that points to the vtable for that class. Assume we have an employee class:

class Employee {
public:
  virtual work();
};

This class will have a vptr in it's structure, so it actually may look like this:

class Employee {
public:
  vtble *vptr;  // hidden pointer
  virtual work();
};

When we derive from this class, it will also have a vptr, and it must be in the same spot (in this case, at the beginning). That way when a function is called, regardless of the type of derived class, it always uses the vptr at the beginning to find the right vtable.

Eidetic answered 3/10, 2010 at 11:11 Comment(5)
Strictly, the use of virtual functions in a constructor is reliable. The result is well defined (other than for pure virtual functions), but not usually that which is desired.Sherronsherry
Hi JoshD, Could you please explain the following line you have told : "When a new object is created during run time, the hidden vtable pointer is set to point to the vtable." As i am beginner i find it difficult to understand it.Alane
Charles is correct, but practically speaking it's not a bad thing to have a general expectation of what compilers actually do - as long as you don't rely on it too much - and your description's realistic. @Sen: if you say Employee e, where Employee is a class with virtual methods, then the new object e typically has space reserved by the compiler for a pointer to the vtable for Employee. If you had President derived from Employee, then its vtable pointer would point to the President vtable, but both vtable pointers will be at the same offset relative to other Employee data members.Groats
@user433534: Could you please expand this line "but both vtable pointers will be at the same offset relative to other Employee data members"?Alane
@Sen: If I tell you that there's an Employee object at address 0x100, you might find the __vptr at offset 0x4, so 0x104. That still is the case if the Employee object is actually a President object.Lineage

© 2022 - 2024 — McMap. All rights reserved.