为 32 位和 64 位处理器强制对齐的 C++ 安全性

C++ Safety of enforcing alignment for 32 and 64 bit processors

我有两个 CPU。一个 32 位和另一个 64 位。我们有一段如下所示的 C++ 代码:

typedef std::bitset<16> MyBits;

typedef struct t_MyStruct_16 {
    uint32_t first;
    int16_t second;
    __attribute__((__aligned__(8))) MyBits st;
} MyStruct_16;

typedef struct t_MyStruct_12 {
    uint32_t first;
    int16_t second;
    MyBits st;
} MyStruct_12;

使用 sizeof 计算 32 位和 64 位处理器的结构大小是否安全?填充的东西怎么样,如果我进行位运算,它会影响代码的行为吗?

谢谢。

在 C++ 中,总是添加填充以满足数据成员的对齐要求。所以这个问题可以改写为,"is alignof(T) the same for 32-bit and 64-bit` builds?"

一般来说,答案是否定的。使用 gcc7 (linux) 编译您的示例,我得到 alignof(MyBits) 在 64 位构建上等于 8,在 32 位构建上等于 4。

由于 POD 结构的对齐方式与具有最高对齐方式的成员的对齐方式相同,并且 sizeof(T) 必须始终是 alignof(T) 的倍数,因此您得到 sizeof(MyStruct_12) 在 64 位版本上是 16,而不是 12。

一个可能的解决方案是在每个成员上强制对齐(使用 alignof__attrbitue__((aligned)))。

如果您使用的是 gcc,一个更简单的解决方案是使用带有强制对齐值的 #pragma pack(push)。例如:

#pragma pack (push, 4)
typedef std::bitset<16> MyBits;

typedef struct t_MyStruct_16 {
     uint32_t first;
     int16_t second;
     MyBits st;
} MyStruct_16;

typedef struct t_MyStruct_12 {
    uint32_t first;
    int16_t second;
    MyBits st;
} MyStruct_12;

#pragma pack(pop)

这会强制每个成员的最大对齐为 4,这应该适用于 32 位和 64 位版本。