I'm analyzing an access violation in our application that occurs because it tries to call a virtual function on an object whose virtual function table points to 0. So I'd like to know at what points in an object's lifetime is the virtual function table pointer not set or explicitly set to zero?
(We use Visual C++ 10 as a compiler.)
The vtable pointer will never be 0 while the object is in a valid state. During construction and destruction, while the object has a dynamic type of an abstract base class, the vtable will point to the abstract base class vtable, which will include pure virtual functions, but the vtable pointer itself will still be non-zero.
The only time the vtable pointer can be zero is before construction or after destruction.
If the vtable pointer is truly zero, then you may have used a VC++ extension such as:
class __declspec(novtable) Base {
public:
Base();
virtual void proc();
};
Here __declspec(novtable) tells the compiler the class doesn't need a vtable, because no virtual functions will be called on it until a derived class has installed its own vtable. If you then call Base::proc() before that has happened, you may get the error.
More likely the vtable itself is non-zero, but function's slot in it is zero, due to the function being pure virtual:
class Base {
public:
virtual void proc() = 0;
};
and then someone called it anyway with code like:
void Derived::proc() {
Base::proc();
// Derived-specific stuff here.
};
This can happen because the author of Derived assumed their override needed to call the Base version, even though the Base version doesn't exist.
Either way, one approach to finding this would be to stop all the base class shenanigans, define the function normally, and see what calls it. Eg:
class Base {
public:
virtual void proc() {
assert( typeof(*this) != typeof(Base) ); // Break-point here.
}
};
Related
I`ve faced with a very interesting issue, i hope you can help me what i am doing wrong here..
class abstract1
{
public:
virtual ~ abstract1(){};
virtual void funk1()=0;
virtual void punk1()=0;
};
class abstract2
{
public:
virtual ~ abstract2(){};
virtual void funk2()=0;
virtual void punk2()=0;
};
class Derived: public abstract1,
public abstract2
{
public:
Derived(){ cout<<"Derived constructor"<<endl;};
~Derived() {cout <<"Derived destructor" <<endl;};
void funk1(){
cout<<"funk1 function in Derived!!!"<<endl;
};
void punk1(){
cout<<"punk1 in Derived!!!"<<endl;
};
void funk2(){
cout<<"funk2 function in Derived!!!"<<endl;
};
void punk2(){
cout<<"punk2 in Derived!!!"<<endl;
};
};
class myapi{
public:
void start(void *_drved){
drved=(abstract2*)_drved;
};
void callback(){
drved->funk2();
drved->punk2();
}
protected:
abstract2* drs;
};
Here I have defined two base classes and one derived class inheriting from these two. main() implementation is as follows:
int main() {
Derived* myderived =new Derived();
myapi* dbmodule= new myapi();
dbmodule->start(myderived);
dbmodule->callback();
return 0
}
I expect to see that funk2 and punk2 are getting called one after another. However result is shockingly new to me . Callback() seems to call funk1 and punk1. Screen output is like below:
Derived constructor
funk1 function in Derived!!!
punk1 in Derived!!!
Hope you can let me know what i am getting wrong here.Thanks
The answers and comments do not quite go down to the bottom of it, so I will try to address this.
On the first look, using void* casts as shown should not be of a problem, because you end up casting to the base, right? So even if at some point the information of the type was lost through void*, it should be re-aquired? The virtual function calls should still work?
They would, if not for multiple inheritance. In single-inheritance scenario, correct virtual functions would be still called. But when you have multiple inheritance, you need to know the type to properly calculate offset to one of the bases.
A bit of background. Virtual functions are usually represented through so-called VTABLE - which can be thought of as a table of pointers to functions. For every specific class there is a copy of such table (per class, not per object!) which will have pointers set to corresponding member functions, defined in that class. Every object of the class has a pointer to this table (so that multiple objects of the same class all share the same table).
For single inheritance, there is only one vtable pointer and it's the first member of the class. As a result, it doesn't matter how you cast your pointer in between, as long as you cast it to correct type before calling virtual function, you will be calling the proper virtual function.
However, in case of multiple non-virtual inheritance, there is more than one ponter to vtable. You have a pointer for every parent! So when you cast to the parent, the resulting pointer would point to one of the bases - by offsetting the pointer to the object to the pointer to vtable of the class you cast to. If you first cast to void*, this crucial step is not performed, and resulting void* is simply pointing to the first vtable in your class. And even when you cast back to the proper base, there is no longer needed information to perform proper offsetting - all the compiler sees is the void*, it would have no ither information - and the pointer remains pointing to the first vtable.
As a result of all this, you end up calling virtual functions from incorrect base!
class base
{
public:
virtual void showbase() {
// ----------
}
};
class base1 {
public:
virtual void showbase1() {
// -------
}
};
class derived : public base, public base1
{
void showbase() {
// ----
}
void showbase1() {
// -------
}
};
int main()
{
base* p = new derived();
p->showbase1();
base1* p1 = new derived();
p1->showbase();
}
As per my understanding about virtual function is that compiler deals it with run time (vtable mechanism), then why I am getting compile time error.
To simulate a compiler, consider what a compiler sees:
class base
{
public:
virtual void showbase() {
// ----------
}
};
base* p = /*blah blah*/;
p->showbase1();
Yes, base is a polymorphic class. And p is indeed a pointer-tobase. But since p points just to a base, and importantly not to a base1 (where showbase1 lives) the compiler interprets the above code like this. Obviously, I'm paraphrasing:
Here is a class named `base` with a single virtual method called `showbase`.
Here is a pointer to a `base` object. Call the method named `showbase1`
And the compiler complains:
Um, excuse me buddy, but base doesn't have a method called
showbase1.
You asked:
[My] understanding about virtual function is that compiler deals with
it at run time. Why I am getting compile time error?
Because the code you've written is nonsense. Here basically is how polymorphism works.
You define a base class with virtual methods.
You define a derived class that overrides those virtual methods.
The compiler creates a vtable which maps the names of the methods in the base class to the implementation in the derived class.
When you call a method in the base class through a pointer (or ref) to the base class, the derived class' implementation is called.
But what you are trying to do is:
Define a base class with virtual methods.
Define a derived class which overrides those virtual methods.
Call a function in a completely different class.
As per my understanding about virtual function is that compiler deals it with run time (vtable mechanism), then why I am getting compile time error.
"Deals with it" is pretty vague and vtables are not magic; In C++ virtual dispatch allows for the actual function called to be one that overrides the statically declared virtual function. That means that the function which is being overridden must be known at compile time.
The vtable does not contain information that would be necessary to look up functions at run-time. Instead, it's basically just a list of pointers to overriding functions. The base provides a complete list of its virtual functions and so, given a particular base type, the compiler knows at compile-time where to go in the vtable for that base for a particular function override; The compiler can generate code that goes directly to that spot in the vtable, gets the pointer, and calls the overriding function.
Then, at run-time, when the actual object of derived type is created, the derived object's constructor fills in the base's vtable, so that anything checking the vtable will get pointers to the derived type's functions.
So the problem with your code is that the function you're calling, showbase(), is not on the list of virtual functions for the type the compiler knows you're accessing, base1; The compiler can't know where in base1's vtable to get a pointer for a function override named showbase(), because there is no such entry in base1's vtable.
A base class pointer to a derived class can only access the member functions defined in the base class. It is illegal to try and access other functions defined in the derived class through it. In your case base class does not define showbase1 and therefore this is illegal
base* p = new derived();
p->showbase1(); //illegal
However, you can do this:
p->showbase(); // legal because showbase is a member function of base
Similarly you can't access showbase1 using a base class pointer
base1* p1 = new derived();
p1->showbase(); //illegal
p1->showbase1(); //legal
Your base class(es) only know about their own member functions, so you can't use it this way. You could do this instead:
base* p = new derived();
p->showbase();
base1* p1 = new derived();
p1->showbase1();
To answer your question about runtime polymorphism, it is dealing with runtime polymorphism (late binding) via the vtable, as you say. But with multiple inheritance, there is essentially a vtable for for each base class. You can't access one base class' vtable via a pointer to the other base class.
p'static type s type is base and hence you can only call with it functions that have been definied into base even if at the end, it will be the functions from derived which will be called because p's dynamic type is derived
Same thing happens for p1.
Maybe you meant p->showbase(); and p1->showbase1();
Following this question - Pure virtual call in destructor of most derived class - I tried some code to check some syntax and discovered that as sucessive destructors are called, they call their relevant virtual functions. Consider this code:
class Base
{
public:
virtual void Method() = 0;
};
class Derived : public Base
{
public:
~Derived()
{
Method();
}
virtual void Method()
{
cout << "D";
}
};
class DoubleD : public Derived
{
public:
~DoubleD()
{
Method();
}
virtual void Method()
{
cout << "DD";
}
};
int main(array<System::String ^> ^args)
{
DoubleD D;
DoubleD E;
return 0;
}
As expected, as the object gets destructed, it calls the correct method (eg first the most derived and then the the second most derived).
Ouput: DD D
My question is, why does this work? Since you are not meant to call virtual functions in a c'tor/d'tor, why does the virtual table "unwind" correctly.
Eg, I can see why the most derived one works, that was the state the virtual function pointer table was in when this started. But why, when Derived's destructor is called, does the table get correctly set to point at that classes implementation of Method.
Why not just leave it, or if it is being nice, set the value to NULL.
Since you are not meant to call virtual functions in a c'tor/d'tor,
why does the virtual table "unwind" correctly.
The premise is wrong. There's nothing wrong with calling virtual functions from a constructor or destructor, provided you know how they work. As you've seen, the dynamic type is the type of the constructor or destructor being run, so you don't get virtual calls to the parts of the object that haven't yet been constructed or have already been destroyed.
The behaviour is perfectly well defined. You shouldn't worry about how your compiler vendor managed to implement it (though it's not very hard to reason out yourself, or just look up).
It's generally not advised to call virtual functions in the destructor because of the non-intuitive behaviour, but there's nothing fundamentally wrong with it.
This is how it is supposed to work according to the standard.
As for why, after you've run the destructor for a derived class you can't count on any of the properties of that class to be valid or consistent. Calling one of the virtual methods at that point would be a disaster if it went into a derived class method.
It's quite likely that the compiler bypasses the vtable altogether, since it already knows which overridden method applies to the current state of the object. That's just an implementation detail though.
Virtual table doesn't get modified at run time after the initial setup at object creation.
On some implementations, Virtual table shall be created as per class basis.
In your example, when DoubleD object is destroyed, it calls method function in DoubleD class, Because, the DoubleD part of the object is not yet destroyed completely.
VTable of DoubleD class has an entry for method function to point to method in its class as it is overridden(in the last level of inheritance)
Once DoubleD is destroyed, now the object type is of type Derived. So the call has to go to the method in vtable of class Derived. Hence the behavior.
I have some doubts regarding virtual function or better we can say Run Time Polymorphism. According to me, I assumed the way it works as below,
A Virtual Table (V-Table) will be created for every class that has at least one virtual member function. I believe this is static table and so it is created for every class and not for every object. Please correct me in this if I am wrong here.
This V-Table has the address of the virtual function. If the class has 4 virtual functions, then this table has 4 entries pointing to the corresponding 4 functions.
Compiler will add a virtual pointer (V-Ptr) as a hidden member of the class. This virtual pointer will point to the starting address in the virtual table.
Assume I have program like this,
class Base
{
virtual void F1();
virtual void F2();
virtual void F3();
virtual void F4();
}
class Der1 : public Base //Overrides only first 2 functions of Base class
{
void F1(); //Overrides Base::F1()
void F2(); //Overrides Base::F2()
}
class Der2 : public Base //Overrides remaining functions of Base class
{
void F3(); //Overrides Base::F3()
void F4(); //Overrides Base::F4()
}
int main()
{
Base* p1 = new Der1; //Believe Vtable will populated in compile time itself
Base* p2 = new Der2;
p1->F1(); //how does it call Der1::F1()
p2->F3(); //how does it call Base::F3();
}
If the V-Table gets populated in compile time, why do call it as Run Time Polymorphism ?. Please explain me how many vtables and vptr and how it works using the above example. According to me 3 Vtables will be there for Base, Der1 and Der2 class. In Der1 Vtable,it has address of F1() and F2() of its own, whereas for F3() and F4() the address will point to Base class. Also 3 Vptr will be added as hidden member in Base, Der1 and Der2 class. If everything is decided at compile time, What happens exactly during the run time ?. Please correct me if I am wrong in the concept.
It's obviously implementation defined, but most implementations
are fairly similar, more or less along the lines you describe.
This is correct.
vtables contain more than just pointers to functions.
There's usually an entry pointing to the RTTI information, and
often some information concerning how to fix up the this pointer
when calling the function (although this can also be done using
trampolines). In the case of virtual bases, there could also be
an offset to the virtual base.
This is also correct. Note that during construction and
destruction, the compiler will change the vptr as the dynamic
type of the object changes, and that in the case of multiple
inheritance (with or without virtual bases), there will be more
than one vptr. (The vptr is at a fixed offset with
respect to the base address of the class, and in the case of
multiple inheritance, not all classes can have the same base
address.)
As to your final remarks: the vtables are populated at compile
time, and are static. But the vptr's are set at runtime,
according to the dynamic type, and the function call uses it to
find the vtable and dispatch the call.
In your (very simple) example, there are three vtable, one for
each class. Because only simple inheritance is involved, there
is only one vptr per instance, shared between Base and the
derived class. The vtable for Base will contain four slots,
pointing to Base::f1, Base::f2, Base::f3 and Base::f4.
The vtable for Der1 will also contain four slots, pointing to
Der1::f1, Der1::f2, Base::f3 and Base::f4. The vtable
for Der2 will point to Base::f1, Base::f2, Der2::f3 and
Der2::f4. The constructor for Base will set the vptr to the
table of Base; the constructor for the derived classes will
first call the constructor for the base class, then set the vptr
to the vtable corresponding to its type. (In practice, in such
simple cases, the compiler is probably capable of determining
that the vptr is never used in the constructor to Base, and so
skip setting it. In more complicated cases, where the compiler
cannot see all of the behavior of the base class constructor,
however, this is not the case.)
As to why it is called runtime polymorphism, consider
a function:
void f(Base* p)
{
p->f1();
}
The function actually called will be different, depending on
whether p points to a Der1 or a Der2. In other words, it
will be determined at runtime.
The C++ standard doesn't specify how virtual function calls have to be implemented, but here's a simplified example of the approach that is universally accepted.
From a high-level perspective, the v-tables would look like this:
Base:
Index | Function Address
------|------------------
0 | Base::F1
1 | Base::F2
2 | Base::F3
3 | Base::F4
Der1:
Index | Function Address
------|------------------
0 | Der1::F1
1 | Der1::F2
2 | Base::F3
3 | Base::F4
Der2:
Index | Function Address
------|------------------
0 | Base::F1
1 | Base::F2
2 | Der2::F3
3 | Der2::F4
When you create p1 and p2, they get a pointer that points to Der1's vtable and Der2's vtable, respectively.
The call to p1->F1 basically means "call function 0 on p1's virtual table".
vptr[0] is Der1::F1, so it gets called.
It's called run-time polymorphism because the function that will be called for a specific object is determined at run-time (by making a look-up in the object's vtable).
It's implementation defined. When programming in C++, the only thing that should concern you is that if you declare a method virtual, the run-time contents of the object behind the pointer or reference will decide what code will be called.
Perhaps you should read about that topic first. Here is the C++ specific stuff.
I'm not going to go through four virtual functions and three derived types. Suffice it to say: for the ultimate base class, the vtable has pointers that point to the base class' version of all the virtual functions. For derived classes, the vtable has pointers to all of the derived class's virtual functions; when the derived class overrides a base class function, the function pointer for that function points to the derived class' version of that virtual function; when the derived class inherits a virtual function, the function pointer points to the inherited function.
I will type an example :
class A
{
public:
virtual ~A(){}
};
class B: public A
{
public:
~B()
{
}
};
int main(void)
{
A * a = new B;
delete a;
return 0;
}
Now in Above Example , destructors will be called recursively bottom to up .
My Question is how Compiler do this MAGIC .
There are two different pieces of magic in your question. The first one is how does the compiler call the final overrider for the destructor and the second one is how does it then call all the other destructors in order.
Disclaimer: The standard does not mandate any particular way of performing this operations, it only mandates what the behavior of the operations at a higher level are. These are implementation details that are common to various implementations, but not mandated by the standard.
How does the compiler dispatch to the final overrider?
The first answer is the simple one, the same dynamic dispatch mechanism that is used for other virtual functions is used for destructors. To refresh it, each object stores a pointer (vptr) to each of its vtables (in the event of multiple inheritance there can be more than one), when the compiler sees a call to any virtual function, it follows the vptr of the static type of the pointer to find the vtable and then uses the pointer in that table to forward the call. In most cases the call can be directly dispatched, in others (multiple inheritance) it calls some intermediate code (thunk) that fixes the this pointer to refer to the type of the final overrider for that function.
How does the compiler then call the base destructors?
The process of destructing an object takes more operations than those you write inside the body of the destructor. When the compiler generates the code for the destructor, it adds extra code both before and after the user defined code.
Before the first line of a user defined destructor is called, the compiler injects code that will make the type of the object be that of the destructor being called. That is, right before ~derived is entered, the compiler adds code that will modify the vptr to refer to the vtable of derived, so that effectively, the runtime type of the object becomes derived (*).
After the last line of your user defined code, the compiler injects calls to the member destructors as well as base destructor(s). This is performed disabling dynamic dispatch, which means that it will no longer come all the way down to the just executed destructor. It is the equivalent of adding this->~mybase(); for each base of the object (in reverse order of declaration of the bases) at the end of the destructor.
With virtual inheritance, things get a bit more complex, but overall they follow this pattern.
EDIT (forgot the (*)):
(*) The standard mandates in §12/3:
When a virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data member) or from a destructor, and the object to which the call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor’s own class or in one of its bases, but not a function overriding it in a class derived from the con- structor or destructor’s class, or overriding it in one of the other base classes of the most derived object.
That requirement implies that the runtime type of the object is that of the class being constructed/destructed at this time, even if the original object that is being constructed/destructed is of a derived type. A simple test to verify this implementation can be:
struct base {
virtual ~base() { f(); }
virtual void f() { std::cout << "base"; }
};
struct derived : base {
void f() { std::cout << "derived"; }
};
int main() {
base * p = new derived;
delete p;
}
A virtual destructor is treated in the same way as any other virtual function. I note that you've correctly maked the base class's destructor as virtual. As such, it is no way different than any other virtual function, as far as dynamic dispatch is concerned. The most derived class destructor gets called through dynamic dispatch but it also automatically results in calls to Base class destructors of the class1.
Most compiler implements this feature using vtable and vptr, though the language specification does not mandate it. There can be a compiler which does this differently, without using vtable and vptr.
Anyway, as it true for most compilers, it is worth knowing what vtable is. So vtable is a table contains pointers of all virtual functions the class defines, and the compiler adds vptr to the class as hidden pointer which points to the correct vtable, so the compiler uses correct index, calculated at compile-time, to the vtable so as to dispatch the correct virtual function at runtime.
1. The italicized text is taken from #Als's comment. Thanks to him. It makes things more clear.
A suitable implementation of (virtual) destructors the compiler might use would be (in pseudocode)
class Base {
...
virtual void __destruct(bool should_delete);
...
};
void Base::__destruct(bool should_delete)
{
this->__vptr = &Base::vtable; // Base is now the most derived subobject
... your destructor code ...
members::__destruct(false); // if any, in the reverse order of declaration
base_classes::__destruct(false); // if any
if(should_delete)
operator delete(this); // this would call operator delete defined here, or inherited
}
This function gets defined even if you didn't define a destructor. Your code would just be empty in that case.
Now all derived classes would override (automatically) this virtual function:
class Der : public Base {
...
virtual void __destruct(bool should_delete);
...
};
void Der::__destruct(bool should_delete)
{
this->__vptr = &Der::vtable;
... your destructor code ...
members::__destruct(false);
Base::__destruct(false);
if(should_delete)
operator delete(this);
}
A call delete x, where x is of pointer to class type, would be translated as
x->__destruct(true);
and any other destructor call (implicit due to variable going out of scope, explicit x.~T()) would be
x.__destruct(false);
This results in
the most derived destructor always being called (for virtual destructors)
operator delete from the most derived object being called
all members' and base classes' destructors being called.
HTH. This should be understandable if you understand virtual functions.
As usual with virtual functions there will be some implementation mechanism (like a vtable pointer) that will let the compiler find which destructor to run first depending on the type of the object. Once the most derived class destructor is run it will in turn run the base class destructor and so on.
It's up to the compiler how to implement it and typically it's done with the same mechanism as other virtual methods. In other words there's nothing special about destructors that requires a virtual method dispatch mechanism that is distinct from that used by normal methods.
A virtual destructor has an entry in the virtual table just as other virtual functions do. When the destructor is invoked -either manually or automatically from a call to delete- the most derived version is invoked. A destructor also automatically calls the destructor for its base classes, so that in combination with the virtual dispatch is what causes the magic.
Unlike other virtual functions, when you override a virtual destructor, your object's virtual destructor is called in addition to any inherited virtual destructors.
Technically this can be achieved by whatever means the compiler chooses, but almost all compilers achieve this via static memory called a vtable, which permits polymorphism on functions and destructors. For each class in your source code, a static constant vtable is generated for it at compile time. When an object of type T is constructed at runtime, the object's memory is initialized with a hidden vtable pointer which points to the T's vtable in ROM. Inside the vtable is a list of member function pointers and a list of destructor function pointers. When a variable of any type that has a vtable goes out of scope or is deleted with delete or delete[], all of the destructor pointers in vtable the object points to are all invoked. (Some compilers choose to only store the most derived destructor pointer in the table, and then include a hidden invocation of the superclass's destructor in the body of every virtual destructor if one exists. This results in equivalent behavior.)
Additional magic is needed for virtual and nonvirtual multiple inheritance. Assume I am deleting a pointer p, where p is of the type of a base-class. We need to invoke the destructor of the sub-classes with this=p. But using multiple inheritance, p and the start of the derived object may not be the same! There is a fixed offset which must be applied. There is one such offset stored in the vtable for each class that is inherited, as well as a set of inherited offsets.
When you have a pointer to an object, it points to a block of memory that has both the data for that object and a 'vtable pointer.' In microsoft compilers, the vtable pointer is the first piece of data in the object. In Borland compilers, it is the last. Either way, it points to a vtable that represents a list of function vectors corresponding to the virtual methods that can be invoked for that object/class. The virtual destructor is just another vector in that list of function pointer vectors.