c++ - 空基类是否会影响派生类的布局?

标签 c++ standards unspecified-behavior

C++ 标准(引用自 n3242 草案)关于子对象 [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 正在采用标准来表示如果类型代表不同的对象,则不能为类型的存储设置别名。我敢打赌 MSVC 正在采用标准来表示如果一个子对象的大小为零,您可以做任何您想做的事。

这是未指明的行为吗?

最佳答案

扩展我之前的评论:

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

不同类型的对象不能这样直接比较,所以允许它们有相同的地址。一个示例是结构及其第一个成员。它们不能是同一类型。基类和派生类也不能,因此如果基类为空,它们可能具有相同的地址。

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

因此,如果成员具有不同的类型(空和字符),它们可以具有相同的地址。如果它们属于同一类型,则它们不能,因为这会破坏对对象身份的测试,例如 if (this != &that),有时用于测试自赋值之类的事情。

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

关于c++ - 空基类是否会影响派生类的布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7760198/

相关文章:

c++ - 我可以获取标准库中定义的函数的地址吗?

c++ - 未定义、未指定和实现定义的行为

c++ - 为 C++ 设置窗口

c++ - 标准是否保证 std::vector 占用的总内存按比例缩放为 C+N*sizeof(T)?

C++ 标记字符串

r - 如何使用预测计算 R 中预测数据的标准误差

c - 这样的代码合法吗?

c++ - C++ 中的指针比较是未定义或未指定的行为吗?

c++ - 图标不是 3.00 格式

c++ - 避免堆碎片的最佳 STL 容器