4

I know that, how to implement virtual function call resolution is not part of C++ standrads nor it says anything about vptr or v-table, but let me ask this question here.

I've heard that v-table is a common technique used by compilers to implement virtual function call resolution. My understading about this is that there is only virtual table is needed per class, per process.

What I am wondering is, when is the v-table is created for a class?
Is it When the class of a given type (which needs a v-table) is created in a process space for the first time?
All other subsequently created objects of that type in that process space, refers to the v-table that is already created?
When would this v-table will be deleted?

I am sorry if this is too subjective or discussion type of question, but these questions lingers in my mind for a while and I feel its OK asking it here.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662
riderchap
  • 667
  • 2
  • 11
  • 19
  • If you want to know you are going to have to tell us what compiler (and version) on which OS and then hope that one of the compiler engineers that wrote the code is here and wants to answer. But even if you do know the information is usless. – Martin York Nov 21 '10 at 18:03
  • If you are interested in implementation details, you should put [Inside the C++ Object Model](http://www.amazon.com/dp/0201834545/) on your wish-list for Christmas. It covers vtables and other stuff in great detail. – fredoverflow Nov 21 '10 at 18:18
  • OK, it could be a static table, not related to the lifetime of the objects, makes sense. – riderchap Nov 21 '10 at 18:19

4 Answers4

7

The v-table is statically allocated and is never deleted, nor is it explicitly allocated. The pointers within any given specific object are constants.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • Well that's just not true. Any object in a dll or shared library can not know the address of the functions until after it is loaded into memory as such the vtables must be constructed at runtime thus the values may be constant once you have loaded but they are not truly constant as in compile time constants. – Martin York Nov 21 '10 at 18:50
  • @Martin York: The vtables are constructed at compile-time by the compiler that compiled whatever linked them, and that inserts the constant pointers into those slots. The address of the functions might not be known to the dll compiler, but they are known to whatever linked against it. The point is that the entire process happens at compile-time. The only thing that happens at runtime is following said pointer. – Puppy Nov 21 '10 at 19:32
  • 2
    How can it happen at compile time when you don't know the address of the methods until runtime. Even the linker does not know the address of a method when it is in a dll. The dll can be loaded anywhere in memory thus the addresses can not be known until after the dll is loaded (this is a runtime operations). Even if you go out of your way to re-base the dll to try and give them explicit addresses the compiler can not guarantee this addresses (as another dll may manually load data into this address space and thus force the dll to be shifted). – Martin York Nov 21 '10 at 21:13
  • 2
    So yes in theory (and for easy reference for beginners and people that have not actually written a compiler) we say that the table is statically created at compile time. Unfortunately the world is a lot more complex and this simple truth does not hold up in the real world (apart from one OS I know of that builds each DLL/application into a fixed location in memory and is never moved or unloaded). The v-tables in reality are constructed at runtime (probably during the loading of dll but who can say for sure (apart from the people who design the systems). – Martin York Nov 21 '10 at 21:20
  • @Martin York: The v-tables are not constructed at runtime, they are merely loaded into memory at run-time, and that memory address patched in. Taking this line of logic, anything is non-constant, as it also must be loaded into memory and any address it uses patched in. The compiler does not call operator new() and allocate a v-table. It is allocated statically within the file that is loaded in to the address space. – Puppy Nov 21 '10 at 21:35
  • @DeadMG: About the only thing correct is that new/delete are not used. The memory used is statically allocated. But it is probably not loaded from the DLL (if so which DLL do you think it is loaded from). There is no one way of doing it (each method I have seen has its own quirks). – Martin York Nov 22 '10 at 04:54
  • @LokiAstari : when build a DLL, the compiler will use a Relative Virtual Address(RVA) to fill in the vtable, just like for any other dll-based addresses. Then in load time, if the dll is not loaded in its base address, the OS (the loader, I think) will rebase everything - this is just an OS adjustment. has nothing to do with vtable - so I would prefer to say vtable is compiler time constant that statically allocated – Baiyan Huang Jul 10 '12 at 13:31
4

The C++ FAQ provides a simplified explanation of the vtable mechanism. You should give it a read, although you will probably have to go through your particular compiler documentation for more details.

The most important ideas from my point of view :

  • The vtable for a type is static and built at compile time
  • Each of the type instances contains a pointer to this table
  • Because this pointer is initialized at construction time, a virtual member function should never be called from the constructor
icecrime
  • 74,451
  • 13
  • 99
  • 111
  • Virtual member function can be called from the constructor. Why it shouldn't be called? – BЈовић Nov 21 '10 at 18:39
  • Yes, you can call virtual methods from the constructor, but you have to know which exactly method will be called. In a general case, I agree with the rule "do not call virtual methods from constructor/destructor", but one size doesn't fit all. – BЈовић Nov 21 '10 at 19:18
  • @VJo: true (that's why I use the word "should" in my answer), although it is obviously undefined in the case of a pure virtual member function – icecrime Nov 21 '10 at 19:26
  • @Martin York: That comment deserves a -1, just wrong. The result is well-defined (calls the virtual function as defined in the base class under construction). Every implementation, vtable-based or otherwise, has to work like this. Common vtable implementations work correctly in these cases, as they set the vtable pointer to the correct vtable (base, not derived). What you can't do is call _overrides_ of virtual methods in derived classes from base class constructors. – MSalters Nov 22 '10 at 10:38
  • @MSalters: I am eating humble pie as you read (Section 12.7 para 4). Mixing up virtual and pure virtual (Section 10.4 para 6) – Martin York Nov 22 '10 at 22:45
1

The vtable is static data so available immediately at load. BTW, it is usually bundled in the compilation unit which contains the definition for the first non-inline virtual function on the class (and that heuristic leads to problem when there is only one virtual function which is inline).

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
0

I believe it's all implementation defined, so it's difficultto give a universal answer to this question. I believe the vtable should be a some sort of a static class member.