How is a vptr initialized at compile time? - c++

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.

Related

Do derived objects cast from base need to use a vtable

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.

Does virtual inheritance and virtual function use the same vtable?

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.

virtual destructor's practical necessity in a particular case

C++03 5.3.5.3
In the first alternative (delete
object), if the static type of the
operand is different from its dynamic
type, the static type shall be a base
class of the operand’s dynamic type
and the static type shall have a
virtual destructor or the behavior is
undefined.
This is the theory. The question, however, is a practical one. What if the derived class adds no data members?
struct Base{
//some members
//no virtual functions, no virtual destructor
};
struct Derived:Base{
//no more data members
//possibly some more nonvirtual member functions
};
int main(){
Base* p = new Derived;
delete p; //UB according to the quote above
}
The question: is there any existing implementation on which this would really be dangerous?
If so, could you please describe how the internals are implemented in that implementation which makes this code crash/leak or whatever? I beg you to believe, I swear that I have no intentions to rely on this behavior :)
One example is if you provide a custom operator new in struct Derived. Obviously calling wrong operator delete will likely produce devastating results.
I know of no implementation on which the above would be dangerous, and I think it unlikely that there ever will be such an implementation.
Here's why:
"undefined behaviour" is a catch-all phrase meaning (as everyone knows), anything could happen. The code could eat your lunch, or do nothing at all.
However, compiler writers are sane people, and there's a difference between undefined behaviour at compile-time, and undefined behaviour at run-time. If I was writing a compiler for an implementation where the code snippet above was dangerous, it would be easy to catch and prevent at compile time. I can says it's a compilation error (or warning, maybe): Error 666: Cannot derive from class with non-virtual destructor.
I think I'm allowed to do that, because the compiler's behaviour in this case is not defined by the standard.
I can't answer for specific compilers, you'd have to ask the compiler writers. Even if a compiler works now, it might not do so in the next version so I would not rely on it.
Do you need this behaviour?
Let me guess that
You want to be able to have a base class pointer without seeing the derived class and
Not have a v-table in Base and
Be able to clean up in the base class pointer.
If those are your requirements it is possible to do, with boost::shared_ptr or your own adaptation.
At the point you pass the pointer you pass in a boost::shared_ptr with an actual "Derived" underneath. When it is deleted it will use the destructor that was created when the pointer was created which uses the correct delete. You should probably give Base a protected destructor though to be safe.
Note that there still is a v-table but it is in the shared pointer deleter base not in the class itself.
To create your own adaptation, if you use boost::function and boost::bind you don't need a v-table at all. You just get your boost::bind to wrap the underlying Derived* and the function calls delete on it.
In your particular case, where you do not have any data member declared in the derived class and if you do not have any custom new/delete operators (as mentioned by Sharptooth), you may not have any problems ,but do you guarantee that no user will ever derive your class? If you do not make your Base's destructor virtual, there is no way for any of the classes derived from Derived to call their destructors in case the objects of derived classes are used via a Base pointer.
Also, there is a general notion that if you have virtual functions in your base class, the destructor should be made virtual. So better not surprise anybody :)
I totally agree with 'Roddy'.
Unless you're writing the code for perverted compiler designed for a non-existing virtual machine just to prove that so-called undefined behavior can bite - there's no problem.
The point of 'sharptooth' about custom new/delete operators is inapplicable here. Because virtual d'tor and won't solve in any way the problem he/she describes.
However it's a good point though. It means that the model where you provide a virtual d'tor and by such enable the polymorphic object creating/deletion is defective by design.
A more correct design is to equip such objects with a virtual function that does two things at once: call its (correct) destructor, and also free its memory the way it should be freed. In simple words - destroy the object by the appropriate means, which are known for the object itself.

When is the v-table created for a class?

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.

Does a pure-virtual object have a pointer to the vtbl?

Does a pure-virtual object have a pointer to the vtbl?
(that probably points to NULL?)
thanks, i'm a little bit confused with all the virtual mechanism.
Don't worry about it. Virtual tables are an implementation detail, and aren't even guaranteed to exist. The more you worry about how it might be done, the less you learn about the actual language.
That said, yes. A concrete class will then set that pointer to point to the correct virtual table.
There isn't technically such a thing as a 'pure-virtual object'. I assume you mean an object with pure-virtual methods? But you can't actually create such an object because it would be abstract and the compiler would complain.
Having said that, while the object is being constructed it is briefly an instance of the abstract class before becoming an instance of the derived class. It will in such a case have a virtual table set the functions it defines. It will probably have NULL for the pure virtual methods. If you try calling that the program will crash.
You can try this out by calling virtual methods in the constructor. You'll find they invoke the base class version if you call the methods in the base class. If you call a pure virtual method it'll crash. (In some cases the compiler will figure out what you are doing and complain instead).
The take home is:
Don't call virtual functions in your constructor, its just likely to be confusing. In fact, in most cases it is best if your constructor just sets its internal status up and does not do anything too complicated.