2017-06-22 1 views
0

私は2つのCPUを持っています。 1つの32ビットと別の64ビット。我々は、次のようなC++コードの一部を持っている:C++ 32ビットおよび64ビットプロセッサのアラインメントの安全性

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; 

は、プロセッサ32と64ビットの両方のための構造体のサイズを計算するためにはsizeofを使用することが安全です?埋め込まれたものはどうすればいいですか?私が少し賢明な操作をすれば、コードの動作に影響を与えますか?

ありがとうございます。

+1

安全とはどういう意味ですか?あなたを殺すつもりはない。 – stark

+0

私が言っていることは、たとえば、もしこのビットセットからハッシュを計算すると、私は32ビットと64ビットに対して異なる結果を得ようとしているのでしょうか? – Yore

+0

'sizeof'には、オブジェクトの型の配列を作成する場合に追加されるパディングが含まれます。 – stark

答えて

1

C++では、データメンバーのアラインメント要件を満たすために常にパディングが追加されます。だから問題は、 "alignof(T)は32ビットと64ビットのビルドで同じですか?"と言い換えることができます。

一般的に、答えはいいえです。あなたの例をgcc7(linux)でコンパイルすると、私はalignof(MyBits)を64ビットビルドでは8、そして32ビットビルドでは4になります。

POD構造体のアライメントは最高の位置合わせを持つメンバーのアライメントと同じであり、かつsizeof(T)は常にalignof(T)の倍数でなければならないので、あなたはsizeof(MyStruct_12)は、16の64ビットのビルドの代わりに、12であることを取得

可能な解決策は、アライメントを強制的に(alignofまたはを使用して)すべてのメンバーに強制することです。

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) 

これは、32ビットの両方で動作し、64ビットビルドべき4にすべてのメンバの最大のアライメントを強制します。

+0

ありがとうございました。それが私の必要なものです。 – Yore

関連する問題