gpt4 book ai didi

c++ - 为什么重复的空基址的存储不与 vtable 指针重叠?

转载 作者:行者123 更新时间:2023-12-02 01:32:27 25 4
gpt4 key购买 nike

考虑这个例子:

#include <iostream>

int main()
{
struct A {};
struct B : A {};
struct C : A, B {};

std::cout << sizeof(A) << '\n'; // 1
std::cout << sizeof(B) << '\n'; // 1
std::cout << sizeof(C) << '\n'; // 2, because of a duplicate base

struct E : A {virtual ~E() {}};
struct F : A, B {virtual ~F() {}};

std::cout << sizeof(E) << '\n'; // 8, the base overlaps the vtable pointer
std::cout << sizeof(F) << '\n'; // 16, but why?
}

(run on godbolt)

在这里您可以看到 struct E正如预期的那样,空基类(1 字节大)使用与 vtable 指针相同的存储空间。

但是对于 struct F ,它有一个重复的空碱基,这种情况不会发生。是什么原因造成的?

我在 GCC、Clang 和 MSVC 上得到了相同的结果。上面的结果适用于 x64,因此 sizeof(void *) == 8 .

<小时/>

有趣的是,对于 struct G : A, B {void *ptr;}; GCC 和 Clang 确实执行 EBO(大小为 8),但 MSVC 不执行(大小为 16)。

最佳答案

因为编译器在struct A后面添加了一个字节填充

F {vptr(8) + A 中的 0 个成员 + 1 个填充(因为 A 为空)+b 中的 0 个} = 9然后编译器添加 7 个字节填充来对齐结构的存储;

E {vptr(8) + A 的 0 个成员} = 8 无需填充

来自微软

Every data object has an alignment-requirement. For structures, the requirement is the largest of its members. Every object is allocated an offset so that offset % alignment-requirement == 0

https://learn.microsoft.com/en-us/cpp/c-language/storage-and-alignment-of-structures?view=vs-2019

编辑:

这是我的演示:

int main()
{
C c;
A* a = &c;
B* b = &c;

std::cout << sizeof(A) << " " << a << '\n';
std::cout << sizeof(B) << " " << b << '\n';
std::cout << sizeof(C) << " " << &c << '\n';

E e;
a = &e;
std::cout << sizeof(E) <<" " << &e << " " << a << '\n';

F f;
a = &f;
b = &f;
std::cout << sizeof(F) << " " << &f << " " << a << " " << b << '\n';

}

输出:

1 0000007A45B7FBB4
1 0000007A45B7FBB5
1 0000007A45B7FBB4
8 0000007A45B7FC18 0000007A45B7FC20
16 0000007A45B7FC38 0000007A45B7FC40 0000007A45B7FC41

如您所见,a 和 b 永远不会相互重叠,并且在多重继承上,vptr 都有自己的指针值

VC2019 x64 build 编译的注释

关于c++ - 为什么重复的空基址的存储不与 vtable 指针重叠?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58878985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com