g ++实现如何处理这种情况? [英] How does the g++ implementation handle this situation?
问题描述
这是这一个的后续问题。
请考虑这个例子:
#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 < \\\
;
std :: cout<< pA ==<< std :: hex<< pA < \\\
;
return 0;在Visual Studio 2010中,输出是(在我的机器上):
pC == 002DEF90
pA == 002DEF94
$ b b(此问题由接受答案解释)。
使用g ++,输出为:
pC == 0x96c8008
pA == 0x96c8008
所以,问题是, g ++处理这种情况?什么使地址相同,当
C
应该有一个vtable? (我知道这是一个实现细节,不要说:)我对这个实现细节感兴趣,好奇心。)解决方案<
$ b $ b一旦
A
获得成员,结果就会改变。然而,只要它没有,编译器不需要为A
生成一个真正的布局,所有重要的是保证每个A
object将具有与任何其他A
对象不同的地址。
编译器只需使用
B
子对象(它继承自A
)的地址作为合适的地址。并且结果是B
和C
具有相同的地址(第一个基本+都有虚拟方法)。另一方面,如果
A
有一个成员OR,如果/ code>是
A
(还有其他条件),则 EBO 不能再应用,您会注意到跳转在地址中。This is a follow-up question to this one.
Consider this 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; }
With Visual Studio 2010, the output is (on my machine):
pC == 002DEF90 pA == 002DEF94(this is explained by the accepted answer of the question).
With g++, the output is:
pC == 0x96c8008 pA == 0x96c8008So, the question is, how does the implementation of g++ handle this case? What makes the addresses the same when
C
should have a vtable? (I know that this is an implementation detail, don't say that :) I'm interested in this implementation detail out of curiosity).解决方案After much fiddling, I finally remembered something.
The Empty Base Optimization.
As soon as
A
gets a member, the result change. However as long as it has none, the compiler is not required to generate a real layout forA
, all that matters is to guarantee that eachA
"object" will have a different address from any otherA
object.Therefore, the compiler simply use the address of the
B
subobject (which inherits fromA
) as a suitable address. And it turns out thatB
andC
have the same address (first base + both having virtual methods).On the other hand, if
A
has a member OR if the first member ofB
is aA
(there are other conditions), then the EBO cannot apply any longer and you'll notice a jump in the addresses.这篇关于g ++实现如何处理这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文