g ++实现如何处理这种情况? [英] How does the g++ implementation handle this situation?

查看:124
本文介绍了g ++实现如何处理这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是这一个的后续问题。



请考虑这个例子:

  #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 == 0x96c8008

So, 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 for A, all that matters is to guarantee that each A "object" will have a different address from any other A object.

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

On the other hand, if A has a member OR if the first member of B is a A (there are other conditions), then the EBO cannot apply any longer and you'll notice a jump in the addresses.

这篇关于g ++实现如何处理这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆