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.
The v-table is statically allocated and is never deleted, nor is it explicitly allocated. The pointers within any given specific object are constants.
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
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).
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.
Related
The above was an interview question.
I understand that as part of the virtual dispatch mechanism, the compiler creates a vTable for each class and inserts an extra pointer (vptr) during compilation. But when exactly does it assign the class' virtual table to this vptr?
How is the vptr initialized at compile time?
Whatever I read over the internet says that the compiler initializes the vptr at compile time, but initialization is a run-time mechanism. Am I wrong?
I don't understand how a compiler would initialize it.
Strictly speaking, this is not covered by the C++ standard. But enough implementations go for this to consider it common wisdom. I'm going to address only single inheritance, since multiple inheritance is way more complicated.
The compiler knows in advance where a type's virtual function table is located (it's the compiler that allocates it). It also knows all of that class type's constructors. So what it has to do is fairly simple, at the beginning of each constructor, add the following (illustrative):
this->_vptr = /*VTable's Address*/;
That's it. This is exceptionally simple, and even works intuitively when overriding. Because a derived class's constructor will just overwrite the pointer value.
And yes, that assignment, naturally, happens at run-time. Even though the table itself may be populated beforehand.
If i have a to call x virtual function on the same object, will the compiler be smart enough to somehow remember the vtable address or it will dig the address on each x call?
Cheers
Whenever there is a virtual function inside definition of a class either through inheritance or normal declaration a vtable is created.
Vtables themselves are generally stored in the static data segment as they are class specific as compared to object specific.Generally whenever an object of a class is created vtable pointer pointing to the vtable of the class is generally stored in the beginning of the object's memory location but it depends on the compiler in the end how it implements the virtual function.
Now as long as the object remains in the memory, It includes pointer to its Vtable.So if you call the virtual function on the same object ,just the pointer to vtable is referenced to get vtable location.No digging of address is required.
There are several good answers to a similar question here:
Cost of a virtual function in a tight loop
In general, to understand the C++ object model and the implementation choices Stroustrup made, I recommend his book "The design and evolution of the C++ language".
If i call an inherited method on a derived class instance does the code require the use of a vtable? Or can the method calls be 'static' (Not sure if that is the correct usage of the word)
For example:
Derived derived_instance;
derived_instance.virtual_method_from_base_class();
I am using msvc, but i guess that most major compilers implement this roughly the same way.
I am (now) aware that the behavior is implementation-specific, i'm curious about the implementation.
EDIT:
I should probaby add that the reason that we are interested is that the function is called a lot of times, and it is very simple, and i am not allowed to edit the function itself in any way, i was just wondering if would be possible, and if there would be any benifit to eliminating the dynamic-dispach anyway.
I have profiled and counted functions etc etc before you all get on my backs about optomization.
Both of your examples will require that Derived has a constructor accepting a Base and create a new instance of Derived. Assuming that you have such a constructor and that this is what you want, then the compiler would "probably" be able to determine the dynamic object type statically and avoid the virtual call (if it decides to make such optimizations).
Note that the behavior is not undefined, it's just implementation-specific. There's a huge difference between the two.
If you want to avoid creating a new instance (or, more likely, that's not what you want) then you could use a reference cast static_cast<Derived&>(base_instance).virtual_method_from_base_class(); but while that avoids creating a new object it won't allow you to avoid the virtual call.
If you really want to cast at compile time what you're looking for is most likely the CRTP http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern which allows you to type everything at compile time, avoiding virtual calls.
EDIT for updated question: In the case you've shown now, I would suspect many compilers capable of statically determining the dynamic type and avoiding the virtual call.
Vtable only come into play when you use pointers or references. For objects, it's always the specific class method which is invoked.
You can simply qualify the call, then there is no virtual function dispatch:
Derived derived_instance;
derived_instance.Derived::virtual_method_from_base_class();
However, I suspect that that would be premature optimization.
Do measure.
There is one little related question. But the topic is entirely different.
Now, one concept is about the function resolution and another is about class resolution ? I am wondering that how is it possible if they are using the same vtable (at least in gcc-4.5) ? Is this a compiler dependent terminology ?
I know that it might appear as basic silly question, but I had never thought of it.
A good reference for this sort of thing is the Itanium ABI - see eg http://mentorembedded.github.com/cxx-abi/abi.html#vtable. Despite the name it's a widely used ABI for C++ and it describes a good, working implementation (although obviously other implementations are possible).
You can solve both problems (virtual function calls and virtual inheritance) if you know the dynamic type of an object given just a pointer to it. Every (polymorphic) object in C++ has precisely one dynamic type, which is determined at the moment when it's constructed. E.g. when you write new Foo, that object has the dynamic type Foo even if you store just a void*.
A vtable is a mechanism to store information about the dynamic type of an object in such a way that it can be retrieved via a base pointer. You can store quite some things in a vtable: function pointers, cast offsets, std::type_info objects even.
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??
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.
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.