在32位平台上的结构中对齐

use*_*741 8 c++ padding alignas

在为32位x86 linux运行以下代码时,我得到了意想不到的结果(编译器标志:g ++ -std = c ++ 14 -m32).我试过gcc和clang.

#include <iostream>
using namespace std;

struct S1
{
  uint64_t a;
  uint32_t b;
};

struct S2
{
  alignas(uint64_t) char a[8];
  uint32_t b;
};

int main()
{
  cout << "sizeof(S1)=" << sizeof(S1) << endl;
  cout << "sizeof(S2)=" << sizeof(S2) << endl;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

sizeof(S1)=12
sizeof(S2)=16
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?为什么S1和S2的尺寸不同?据我了解,64位整数值在32位x86机器上与32位对齐.这解释了为什么S1的大小是12个字节.但为什么这不适用于S2呢?

eca*_*mur 4

关键字alignof衡量类型作为完整对象的对齐情况;即当它被分配为单个对象或数组元素时。这不一定与该类型作为子对象的对齐要求相同;POD 结构或标准布局类型的成员是否保证根据其对齐要求进行对齐?

x386 ABI 规定结构体中 64 位整数的对齐方式为 4 个字节;gcc 不能随意更改此设置,因为这会破坏与其他目标文件和程序的二进制兼容性。但是,它可以将完整对象 64 位整数对齐到 8 字节,因为这样做不会影响 ABI,并且可以更有效地访问内存。