Comparison of C++ and Java (VIII): Vtable vs. Method Invocation Table and Binary Compatibility (1)
Both Java and C++ have mechanisms to support dynamic polymorphism via run-time method binding, C++ uses vtable to achieve this goal while Java is by method invocation table. The difference of these two mechanisms leads to the different behaviours regarding to binary compatibility.
A vtable exmple
Considering the following example. Class A defines one virtual function methodA which just prints out a silly message:
class A{
public:
A(){}
virtual void methodB();
};
A.cc
void A::methodA(){
cout<<"print from method A "<<endl;
};
vtable layout of class A:
A::_ZTV1A: 3u entries
0 0u
8 (int (*)(...))(&_ZTI1A)
16 A::methodA
Here is a test class to reference class A:
test.cc
int main (int argc, char *argv[]){
A* a = new A();
a->methodA();
}
We compile and link program by the following three steps:
and run test program
>>./test
and get output:
>>Print from method A
In the example above, method call a->methodA fetches methodA from a address with offset 16.
Adding a virtual method breaks binary compatibility in C++To show this, we add a virtual function methodB to class A right BEFORE methodA :
A.h
class A{
public:
A(){}
virtual void methodB(); // a new added function
virtual void methodA();
};
A.cc
void A::methodA(){
cout<<"print from method A "<<endl;
}
void A::methodB(){
cout<<"print from method B "<<endl;
}
>>./test
and get out put:
>>Print from method B
vtable of revised class A
A::_ZTV1A: 4u entries
0 0u
8 (int (*)(...))(&_ZTI1A)
16 A::methodB
24 A::methodA
This problem shown above is known as "constant recompilation problem" and is usually considered as a side effect of C++: because C++ compiler references methods or variables by numeric offset at compilation time, sometimes we add a new method or a new instance variable to a class, any and all classes that reference that class will require a recompilation, or they break.
3 comments:
I might be wrong, but I'm pretty sure the C++ standard does not require the use of vtables.
Thanks for the nice short post.
I think C++ needs the vtable, otherwise no virtual functions could be realized.
There are other ways to achieve virtual functions... Smalltalk, Ruby, and Python don't use vtables for instance.
That said, while the C++ standard doesn't directly require vtables, it essentially does indirectly. While it's theoretically possible to implement it another way, there's no reason to: the other ways are slower, and they don't buy you anything in a statically-typed language like C++.
Post a Comment