struct tag_t_ {
u_int8_t op;
u_int8_t num;
u_int32_t labels[5];
};
上記の構造では、64 ビット コンパイラによって追加されるパッド バイトはどこにあるのでしょうか?
最初のラベルの前ですか、それとも最初のラベルの最後ですか?
パディングが最初のラベルの最後にある場合、32 ビット アーキテクチャで最初のラベルにアクセス (読み取り) するときに誤った結果が生じるでしょうか?
コンパイラに依存します。適用して保持できる普遍的なルールはありません。
もちろん、32ビットアーキテクチャではコンパイラが異なるため、質問の後半についてはわかりません。構造を直接転送することは決して良い考えではありません。
パディングが原因でsizeof (tag_t_)
、64 ビット マシンで外部メディアにバイトを書き込み、メディアを転送してからsizeof (tag_t_)
32 ビット マシンで読み取ろうとすると、失敗します。だから、それをしないでください。構造体をフィールドごとにシリアライズし、同じ方法でデシリアライズします。
これを 64 ビット システムで実行しています。構造体のメモリ マップは次のとおりです。
offset: variable
0: op num
2: 00 00 // only 2 paddings
4: label0
8: label1
...
20: label5
sizeof(構造体) == 24
// ここでは、構造体のサイズに影響を与えずに、char と最初の 32 ビット整数の間に unsigned short を入れることができます。
構造体パディングの規則は、幅 W の基本変数はすべてその幅に揃えられるというものです。2 番目のパラメーターとして double を指定すると、 の後に 7 バイトのパディングが発生し、 の後op
には 3 バイトだけのパディング バイトが発生します。これnum
は、labels[0] が 4 で割り切れるオフセットで始まるためです。
32/64 ビット システムには違いがあります。32 ビット システムでも 8 バイト変数が 32 ビット境界に整列されます。64 ビット システムでは、long int と double が 8 バイト境界に揃えられます。
これにより、その構造体を 32 ビット システムで安全に使用できるようになります。構造体に double がある場合でも、変数を慎重に計画することで構造体に互換性を持たせることができます。
通常、パディングは各フィールドの最後に適用されます。いいえ、64 ビットでコンパイルされたバイナリは 32 ビット バイナリと互換性がありません。そのため、32 ビット アーキテクチャ用にすべてを再コンパイルする必要がある場合があります。
アライメントは 32 ビット コンパイラによって処理され、それに応じてアドレスが生成されます。