一个空的基类是否会影响派生类的布局? [英] Should an empty base class affect the layout of the derived class?

查看:189
本文介绍了一个空的基类是否会影响派生类的布局?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++标准(引自草案n3242)说明了关于subobjects [intro.object]的以下内容:

The C++ standard (quoting from draft n3242) says the following about subobjects [intro.object]:


位字段或零基本类子对象
大小,该对象的地址是它
占据的第一个字节的地址。两个不同的对象,既不是位字段也不是基本的
类子对象零大小应具有不同的地址。

Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two distinct objects that are neither bit-fields nor base class subobjects of zero size shall have distinct addresses.

给定以下代码段:

struct empty { };
struct member: empty { };
struct derived: empty { member m; };

int main(void)
{
    printf("%d", sizeof(derived));
    return 0;
}

gcc我相信打印输出 2 ,Visual C ++ 2010打印出 1 。我怀疑gcc正在采取的标准,意味着你不能别名存储的类型,如果他们表示不同的对象。

gcc I believe prints out 2, and Visual C++ 2010 prints out 1. I suspect gcc is taking the standard to mean you can't alias the storage of types if they represent different objects. And I bet MSVC is taking the standard to mean if one subobject is zero sized, you can do whatever you want.

这个未指定的行为是什么?

Is this unspecified behavior?

推荐答案

扩展我之前的评论:

对象由其地址标识。如果比较同一类型的两个对象的地址(如指针),并且它们比较相等,则指针指向同一对象。

An object is identified by its address. If you compare the addresses (like pointers) of two objects of the same type and they compare equal, the pointers are considerd to point to the same object.

不同对象类型不能以这种方式直接比较,因此它们被允许具有相同的地址。一个例子是结构体及其第一个成员。它们不能是相同类型。

Objects of different types cannot be compared directly this way, so they are allowed to have the same address. One example is a struct and its first member. They cannot be of the same type. Neither can a base class and a derived class, so they could possibly have the same address if the base class is empty.

但是,一个基类和第一个成员(如果基类是空的话)派生类可以具有相同的类型。这不是一个问题,除非基类也是空的,编译器尝试空基类优化。在这种情况下,我们可以有指向相同类型的两个不同对象的指针比较相等,因此相信它们是同一个对象。

However, a base class and the first member of the derived class can be of the same type. This is not a problem unless the base class is also empty and the compiler tries the empty base class optimization. In that case we could have pointers to two different objects of the same type compare equal, and therefore believe that they were the same object.

因此,如果成员有不同类型(空和char),它们可以具有相同的地址。如果他们是相同的类型,他们不能,因为这会打破对象身份的测试,如 if(this!=& that),有时用于测试自我

So, if the members have different types (empty and char) they can have the same address. If they are of the same type they cannot, because that would break tests for object identity like if (this != &that), sometimes used to test for things like self assignment.

顺便说一下,微软同意这是他们的编译器中的一个错误,但有其他更紧急的事情需要修复。

By the way, Microsoft agrees that this is a bug in their compiler but have other, more urgent, things to fix first.

这篇关于一个空的基类是否会影响派生类的布局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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