【问题标题】:alignment of struct in C++C++中的结构对齐
【发布时间】:2014-03-19 19:58:24
【问题描述】:

范围在 x86
例如,我们有一个这样的结构:

struct X{
   int    a;   
   char   b; 
               // compiler will pad 3 bytes here
   double c;
};
X x;

我认为x的对齐应该是其中最大的成员,本例是double,也就是8字节,
所以&x 应该是 8 的倍数,对吗?

但是,经过一些测试,我的编译器 (msvc 2013) 说 &x 也可以是 4 的倍数,但不能是 8

不是说&x.c 也是4的倍数吗?

我在哪里误解了?

【问题讨论】:

标签: c++ memory-alignment


【解决方案1】:

C 和 C++ 标准没有给出任何关于对齐方式的建议 [或至少没有明确的规则]。由每个编译器(当然还有编译器的目标)来确定一个好的策略。如果此政策适用于目标,通常是首选... ;)

由于 x86 的 FPU [包括标量模式下的 SSE] 可以从任何字节地址读取“双精度”,我相信在 bc 元素之间添加超过 3 个字节没有直接好处,也不要将整个结构对齐到超过 4 个字节。做更多会浪费内存。

在其他一些架构中,这可能是一个很大的好处(或要求目标正确运行),因此它将整个 struct 对齐到 8 个字节。

【讨论】:

    【解决方案2】:

    VC 中的结构对齐是一个编译器选项 /Zp 决定了结构将被打包的字节边界。这通常是一个高级选项,除非在不寻常的用例中(例如对块数据进行 memcpy 以通过网络传输),否则不使用。 检查项目的属性页以查看对齐方式。

    http://msdn.microsoft.com/en-us/library/xh3e3fd0.aspx

    【讨论】:

      【解决方案3】:

      一般来说,您不能说太多关于大小、对齐方式或 struct 的打包方式,“一般”是指根据您选择的 C++ 标准。

      问题是:

      • intchardouble 没有根据标准定义大小,the standard simply sets some minimum requirements,你将得到什么取决于实现
      • 对齐不仅取决于编译器实现,有时甚至取决于您传递的标志集和您的目标硬件,打包对于 CPU 缓存非常重要,有些指令甚至可能需要不同的填充,这也取决于关于您在 struct 中添加的内容以及您的写作方式。

      因此,对于此类操作,您必须严格遵守您选择的编译器的文档并深入了解它为您提供的功能,例如,您可以在此处找到关于 how to pack data in gcc vs msvc 的概述。

      【讨论】:

      • 没什么。根据定义 1。请查看我在注释下提供的链接。
      • @JanHerrmann 来自您发布的链接:“根据计算机体系结构,一个字节可能包含 8 位或更多位”,现在再次告诉我们根据C++ 标准。而不是在字节方面,在位和对齐方面,如果你能做到,你就赢了。
      • 根据我提供的链接sizeofcharsigned charunsigned char的标准中定义返回1。而alignof(en.cppreference.com/w/cpp/language/alignof)返回最小对齐。 intdouble 的大小是实现定义的,但不是char 的大小。所以你的第一点是不正确的。
      • @JanHerrmann 重读一遍,你错了,sizeof 运算符返回字节,即使你知道一个东西是 1 个字节但你无法定义一个字节是多少,你什么都不知道关于类型的大小,就这么简单。
      猜你喜欢
      • 2013-07-24
      • 2014-02-19
      • 2012-05-02
      • 2016-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多