我如何理解 fdump-class-hierarchy 输出

2023-11-22

我正在使用 fdump-class-hierarchy 编译器选项,但我不知道如何理解输出。 “大小”、“对齐”、“基本大小”和“基本对齐”是什么意思?它们是如何计算的?谢谢!

当代码为:

class A
{
public:

private:
    double m_nothing;
    int m_number;
};

输出是:

Class A
   size=16 align=8
   base size=16 base align=8
A (0x406c690) 0

但是,如果我稍微改变一下课程:

class A
{
public:

private:
    int m_number;
    double m_nothing;
};

输出将是:

Class A
   size=16 align=8
   base size=12 base align=8
A (0x406c690) 0

The size and align是用作完整类型时类的大小和对齐方式。也就是说,如果您创建的对象的完整类型是该类型(例如定义该类型的变量,或者将该类型与new).

大小只是它占用的字节数。所以size=16表示当用作完整类型时,它始终占用 16 个字节。

对齐方式告诉您可以放置​​对象的位置:align=8表示对象的地址必须是8的整数倍。

The base size and base align给出该类用作基类时的大小和对齐方式。它们不同的原因是 C++ 标准允许对象在用作基类时使用更少的填充。

所以让我们具体看看你的例子(我假设你实际上有int之前double在第一种情况下)。我也省略了public and private因为在这里他们不会改变任何东西(如果你有公共或私人数据成员,他们could原则上改变一些东西,但我不知道是否有任何编译器利用了这一点)。我也在猜测的大小和对齐方式int and double(实际上我假设的值是非常常见的选择,并解释你得到的值)。

所以在第一种情况下(我假设)你有

class A
{
  int m_number;
  double m_nothing;
};

Now int有大小和对齐方式4,并且 double 具有大小和对齐方式8.

因此,让我们完成编译器的工作并构建我们的类。

首先,我们有m_number,占用4个字节。我们必须按照给定的顺序放置成员,所以m_number开始于A:

iiii

到目前为止,我们的大小为 4(int 的四个字节),对齐方式为 4(因为 int 的对齐方式为 4)。但现在我们必须添加一个双精度(大小和对齐方式 8)。由于直接在 int 之后,我们位于(相对)地址 4,因此我们没有正确对齐 double,因此我们必须添加 4padding字节(我将用它标记*) 得到 8 的倍数。因此我们的类得到:

iiii****dddddddd

现在,如果将该类用作基类,我们就完成了。因此我们有base size=16 and base align=8(我们需要对齐 8 才能正确对齐双精度)。

对于完整的对象,还有另一个考虑因素:标准要求在数组中,对象彼此跟随,中间没有间隙。也就是说,该对象之后的第一个字节必须与下一个对象正确对齐。这最终意味着完整对象的大小必须是其对齐方式的倍数。

现在我们发现的对象布局已经满足了这个要求。因此,我们也可以将其用于完整的对象,无需更改。因此我们得到size=16 and align=8对于完整的对象。

现在考虑顺序颠倒的情况:

class A
{
  double m_nothing;
  int m_number;
};

现在我们必须从double:

dddddddd

接下来,我们必须添加int。事实证明,下一个空闲位置已经正确对齐int,因此我们可以附加它:

ddddddddiiii

现在我们已准备好用作基础对象。正如你所看到的,我们只需要 12 个字节,因此base size=12。当然对于double为了正确对齐,对象必须再次从 8 的倍数的地址开始。因此我们有base align=8.

然而,对于作为完整对象的 sue,我们现在发现下一个地址将位于位置 12,即not正确对齐double成员。因此,我们必须添加填充字节,直到再次到达正确对齐的地址:

ddddddddiiii****

正如你所看到的,现在我们需要 16 个字节,因此size=16。我们还有align=8由于双.

请注意,对齐要求会极大地影响类的大小。例如,考虑以下两种类型:

struct S1
{
  char c1;
  double d1;
  char c2;
  double d2;
  char c3;
};

struct S2
{
  double d1;
  double d2;
  char c1;
  char c2;
  char c3;
};

虽然两者都包含相同的成员,S1具有上述尺寸和对齐方式的总(非基础)尺寸为 40,而总尺寸为S2将只有 24。事实上,类型的对象S1作为完整的对象,看起来像

c*******ddddddddc*******ddddddddc*******

而那些类型S2看起来像

ddddddddddddddddccc*****

因此,最重要的是,具有最高一致性要求的成员应该始终排在第一位。

另请注意sizeof返回完整对象的大小,即类层次结构转储调用的内容size.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我如何理解 fdump-class-hierarchy 输出 的相关文章

随机推荐

  • 使用关联数组的 D3 日历视图

    我想创建一个日历视图 如下例所示 http bl ocks org 4063318 其实我正在尝试修改它 我有一个像这样的关联数组 AdminCourt 2012 10 02 2 2012 10 09 2 2012 10 16 1 Cons
  • Java 无法使用正则表达式 \s,显示:无效的转义序列

    我想用 替换字符串中的所有空白字符 用 ss 替换所有 它对于 效果很好 但不知何故 eclipse 不允许我使用 s 作为空白 我尝试了 t 但它也不起作用 我收到以下错误 无效的转义序列 有效的转义序列 是 b t n f r 这是我的
  • 将元素值反序列化为字符串,尽管它包含混合内容

    假设这样的 XML
  • 将数据框日期列的 dd-mm-yyyy 日期格式更改为 yyyy-mm-dd [重复]

    这个问题在这里已经有答案了 我有这个熊猫数据框df Name Date Score Score2 Joe 26 12 2007 53 45 53 4500 Joe 27 12 2007 52 38 52 7399 Joe 28 12 200
  • 单元测试控制台 C# 应用程序的最佳方法

    我有一个简单的控制台应用程序 它是用一个普通的 main 来触发的 整个程序都在 main 中 它使用命令行解析器库 然后 我在解决方案中有第二个项目 其中包含应用程序的单元测试 但我似乎没有找到从测试中启动主程序进程的好方法 我当前实际启
  • 如何获取UIImage的dpi/ppi?

    iOS 中如何获取图像的 dpi ppi 也许原始图像文件包含这些信息 所以我可以从 NSData 获取 ppi dpi 谢谢 要从 NSData 中存储的图像中提取 DPI 请在项目中包含 Apple 的 ImageIO 框架并使用以下命
  • ASP.NET MVC3:通过控制器加载图像

    我尝试使用来自的答案here 但没有成功 我有以下代码 public ActionResult ShowImage using FileStream stream new FileStream Path Combine Server Map
  • 在 Jupyter Notebook 中使用 Tkinter

    我刚刚开始使用 Tkinter 并尝试在 python 中创建一个简单的弹出框 我从网站上复制粘贴了一段简单的代码 from Tkinter import master Tk Label master text First Name gri
  • 如何在kafka中创建新的消费者组

    我按照快速入门指南上的说明在本地运行 kafkahere 然后我在中定义了我的消费者组配置config consumer properties这样我的消费者就可以从定义的中选择消息group id 运行以下命令 bin kafka cons
  • 在 Twitter Bootstrap 的 ScrollSpy 中,我到底可以在哪里放置 data-spy="scroll" ?

    文档上说得很清楚 只需将 data spy scroll 添加到您想要监视的元素 最典型的是主体 但看来只有戴在身上才能发挥作用 当我将其放入我想要监视的任何其他元素时 导航的最后一个元素将被选中 Here它在身体上 并且有效 并且this
  • 默认打印 XSLT 1.0 文本节点

    我看过XSL xsl 模板匹配 但那里没有提到触发我的问题的匹配模式 我有一个相当复杂的 XML 结构
  • 使用openGL截屏并保存为png

    我正在尝试截取全屏屏幕截图并将其另存为 png 格式 我找到了一个代码here并对其进行了一些修改 对于屏幕截图 我使用 openGL 和 Glut 并使用 c 的 gd 库以 png 格式保存 我得到的只是一张黑色的 png 我不明白为什
  • Google Chrome 扩展开发中的 ES6 模块(意外标记)

    是否可以在 Google Chrome 扩展开发中使用 ES6 模块 我收到 意外的令牌导出 或 意外的令牌导入 好吧 您可以在 Chrome 的兼容性表中看到 并非所有内容都可用 Chrome 擅长在每个版本中添加 ES6 功能 但目前不
  • datatrigger 绑定到 viewmodel 属性

    我正在尝试创建一个简单的样式数据触发器 该触发器从视图模型属性中提取其绑定值 如下所示
  • Android - 从密钥库导出单个密钥/别名

    我有一个密钥库 JKS 其中包含不同应用程序的许多密钥条目 别名 现在 一个应用程序将移至另一位开发人员 我想为他导出 提取单个密钥 别名 gt keytool exe list keystore Keystorefile Keystore
  • 在 Linq to SQL 中设置外键

    众所周知 如果实体已加载 则无法直接在 Linq to SQL 中设置外键 ID 但是 您可以通过外键查找实体 然后使用实体关系将实体设置为外部实体 为了简单起见 我在这里取出了枚举并使用整数值 即 如果我有一个已加载的约会实体和关联的 A
  • 对 pthread_create 的未定义引用

    我有这个代码 include
  • Android 中 raw 和 asset 文件夹的存储限制

    我想将一些视频 音频文件存储在我的应用程序的原始文件夹中 我不知道 raw 和 asset 文件夹的存储限制 谁能告诉我可以在原始文件夹和资产文件夹中存储多少数据 另外 如果我将大量数据存储在这些文件夹中 是否会影响执行速度或从市场下载的应
  • 非托管 DLL 无法在 ASP.NET 服务器上加载

    这个问题涉及一个 ASP NET 网站 最初是在 VS 2005 中开发的 现在是在 VS 2008 中开发的 该网站使用两个非托管外部 DLL 它们不是 NET 我没有编译它们的源代码 必须按原样使用它们 该网站在 Visual Stud
  • 我如何理解 fdump-class-hierarchy 输出

    我正在使用 fdump class hierarchy 编译器选项 但我不知道如何理解输出 大小 对齐 基本大小 和 基本对齐 是什么意思 它们是如何计算的 谢谢 当代码为 class A public private double m n