【发布时间】:2022-01-09 08:10:03
【问题描述】:
在以下示例中,结构 E 继承结构 C 和 D,并且没有其他数据成员:
struct A{};
struct B{};
struct C : A, B {};
struct D : A, B {};
struct E : C, D {};
int main() {
static_assert(sizeof(C) == 1);
static_assert(sizeof(D) == 1);
//static_assert(sizeof(E) == 2); // in Clang and GCC
static_assert(sizeof(E) == 3); //in MSVC
}
在我测试过的所有编译器中,sizeof(C)==1 和 sizeof(D)==1,并且仅在 MSVC 中 sizeof(E)==3 超过其父/成员的总大小,演示:https://gcc.godbolt.org/z/aEK7rjKcW
其实我希望能找到sizeof(E) <= sizeof(C)+sizeof(D)(在空基优化的情况下更少)。而且这里几乎没有任何填充,否则sizeof(E) 将是 2 或 4。
E 中的额外空间 (sizeof(E)-sizeof(C)-sizeof(D) == 1) 的用途是什么?
【问题讨论】:
-
由于EBO,我实际上对 MSVC 的输出感到惊讶
-
您创建了一个“钻石继承”形状。 IE。基类 A 和 B 在 E 中存在两次。除非您进行虚拟继承,否则您没有这样做。现在有趣的问题是,在那些编译中,
sizeof(E) == 1,他们如何实现,E e; assert(static_cast<A*>(static_cast<C*>(&e)) !=static_cast<A*>(static_cast<D*>(&e)));? -
@BitTickler:我检查了偏移量——他们将
D放在偏移量 1 处。gcc.godbolt.org/z/8r9384fK8 -
好吧 - 也许我的断言不是块上最尖锐的断言......但你在 E 中有 2*A 和 2* B。所以你应该能够为它们获得 4 个不同的地址,是吗?
-
@BitTickler:
A和B允许拥有相同的地址。不允许使用不同的As 和不同的Bs。
标签: c++ visual-studio sizeof