对相同基类的引用必须在内存中具有单独的偏移量

cod*_*ave 8 c++ sizeof diamond-problem

我发现这个程序的编译器之间存在一些不一致,

struct A {
};

struct B : public A {
    float m;
};

struct C : public A {
    B b;
    float n;
};

struct D : public A {
    float n;
    B b;
};

static_assert(sizeof(A) == 1, "");
static_assert(sizeof(B) == 4, "");
static_assert(sizeof(C) == 8, ""); // most compilers say this is 12
static_assert(sizeof(D) == 8, "");
Run Code Online (Sandbox Code Playgroud)

大多数编译器断言sizeof(C)== 8说sizeof(C)实际上是12.我发现的唯一编译器没有,并说它是8是Microsoft Visual Studio 2010.

我被告知的原因是,比我更聪明的人,是B中有两个单独的A参考,需要保留彼此不同的个体偏移.首先,从C导出的A在偏移0处,并且第二个A内部成员b不能与第一个A在0处的偏移量相同,因此插入了4个字节的填充.

由于大多数编译器已经实现了这种行为,我想知道你需要什么案例来确保两个A都有不同的引用?寻找一些关于为什么会这样的直觉?

有人说这可能是标准要求的条件,我们很好奇它的原因是什么?

谢谢

Die*_*ühl 3

标准明确规定同一类型的每个对象的地址是不同的。相关条款为 5.10 [expr.eq] 第 1 段:

相同类型的两个指针比较相等当且仅当它们都为空、都指向相同的函数或者都表示相同的地址时(3.9.2)。

这是区分这两个对象所必需的。对象既有价值又有身份。对于基类子对象,与包含类具有相同的地址是合理的。对于类的成员,可以通过两个对象的类型来区分其身份,即它们可以具有相同的地址。对于同一类型的两个对象,您仍然需要一些东西来区分对象的身份。