C ++实现32位和64位处理器对齐的安全性

时间:2017-06-22 13:34:37

标签: c++ alignment bitset type-safety

我有两个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位处理器的结构大小是否安全?那些填充的东西,如果我做一些明智的操作会影响代码的行为吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

在C ++中,始终添加填充以满足数据成员的对齐要求。所以这个问题可以改为,#34; {32}和64位`版本的alignof(T)是一样的吗?&#34;

一般来说,答案是否定的。使用gcc7(linux)编译你的例子,我在64位版本上得到alignof(MyBits)等于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位版本。