How does the g ++ implementation handle this situation?

This is the next question of this .

Consider the following example:

#include <iostream> class A { }; class B : public A { public: int i; virtual void Func() = 0; }; class C : public B { public: char c; void Func() {} }; int main() { C* pC = new C; A* pA = (A*)pC; std::cout << "pC == " << std::hex << pC << "\n"; std::cout << "pA == " << std::hex << pA << "\n"; return 0; } 

In Visual Studio 2010, the output (on my machine):

  pC == 002DEF90
 pA == 002DEF94

(this is explained by the accepted answer).

With g ++ output :

  pC == 0x96c8008
 pA == 0x96c8008

So the question is, how does the g ++ implementation handle this case? What makes addresses the same if C should have a vtable? (I know that this is a detail of the implementation, don’t say that :) I am interested in this implementation detail out of curiosity).

+6
source share
1 answer

After long grunts, I finally remembered something.

Optimization of an empty base .

As soon as A receives a member, the result will change. However, as long as it is absent, the compiler does not need to generate a real layout for A , all that matters is to ensure that each A β€œobject” has a different address from any other object A

Therefore, the compiler simply uses the sub-address of B (which inherits from A ) as a suitable address. And it turns out that B and C have the same address (first base + both have virtual methods).

On the other hand, if A has an OR element, if the first member of B is A (other conditions exist), then EBO can no longer be applied and you will notice a jump in addresses.

+5
source

All Articles