gpt4 book ai didi

c++ - 当我从虚拟基派生 D 时,为什么 VS2015 中的 sizeof(D) 增加了 8 个字节?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:45:19 25 4
gpt4 key购买 nike

我正在使用 C++14 §3.11/2 中的示例:

struct B { long double d; };
struct D : virtual B { char c; }

在 clang、g++ 和 VS2015 中运行下面的代码片段之后

#include <iostream>
struct B { long double d; };
struct D : /*virtual*/ B { char c; };

int main()
{
std::cout << "sizeof(long double) = " << sizeof(long double) << '\n';
std::cout << "alignof(long double) = " << alignof(long double) << '\n';

std::cout << "sizeof(B) = " << sizeof(B) << '\n';
std::cout << "alignof(B) = " << alignof(B) << '\n';

std::cout << "sizeof(D) = " << sizeof(D) << '\n';
std::cout << "alignof(D) = " << alignof(D) << '\n';
}

我得到了以下结果:

                         clang           g++         VS2015  
sizeof(long double) 16 16 8
alignof(long double) 16 16 8
sizeof(B) 16 16 8
alignof(B) 16 16 8
sizeof(D) 32 32 16
alignof(D) 16 16 8

现在,取消上面代码中struct D定义中的virtual的注释,再次运行clang、g++和VS2015的代码,得到如下结果:

                         clang           g++         VS2015  
sizeof(long double) 16 16 8
alignof(long double) 16 16 8
sizeof(B) 16 16 8
alignof(B) 16 16 8
sizeof(D) 32 32 24
alignof(D) 16 16 8

我对上面得到的结果毫无疑问,只有一个异常(exception):为什么 sizeof(D) 在 VS2015 中从 16 增加到 24?

我知道这是实现定义的,但对于这种大小的增加可能有一个合理的解释。如果可能的话,这是我想知道的。

最佳答案

如果您实际使用虚拟继承的虚拟方面,我认为对 vtable 指针的需求就会变得很清楚。 vtable 中的一项可能是 B 开头相对于 D 开头的偏移量。

假设 E 实际上继承自 B 并且 F 继承自 ED 这样 F 中的 D 最终使用 E 中的 B 作为其基类。在不知道它是 F 的基类的 D 方法中,如果没有信息存储在虚表?

因此 clang 和 G++ 将 8 个字节的填充更改为 vtable 指针,而您认为没有变化。但是 VS2015 从来没有那个填充,所以它需要为 vtable 指针添加 8 个字节。

也许编译器注意到 vtable 指针的唯一用途是在计算基指针的低效方案中。所以也许这被优化为简单地拥有一个基指针而不是一个虚表指针。但这不会改变对 8 个字节的需求。

关于c++ - 当我从虚拟基派生 D 时,为什么 VS2015 中的 sizeof(D) 增加了 8 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34179352/

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