それが正常なのかコンパイラのバグなのかわかりませんが、多くのメンバーを持つC構造体があります。その中には、次のものがあります。
struct list {
...
...
const unsigned char nop=0x90; // 27 bytes since the begining of the structure
const unsigned char jump=0xeb; // 28 bytes since the begining of the structure
const unsigned char hlt=0xf4; // 29 bytes since the begining of the structure
unsigned __int128 i=0xeb90eb90eb90eb90f4f4 // should start at the 30th byte, but get aligned on a 16 byte boundary and starts on the 32th byte instead
const unsigned char data=0x66; // should start at the 46th byte, but start on the 48th instead.
}; // end of struct list.
私のプログラムが機能していない理由を見つけるのに苦労しましたが、ようやく見つかりましたhlt
とi
の間に2バイトのギャップがありますこれは0x0に設定されています。これは、i
が整列していることを意味します。
構造体のその部分を印刷すると、これは非常に明確です。
for(int i=28;i<35;i++)
printf("%02hhX",buf[i]);
画面にEBF40000EB90EB90
が表示されます。
プログラムでvolatile struct list data;
などを試しましたが、配置の問題は変わりませんでした。
#pragma
type内でi
を整列しないようにgccに指示する__attribute__
またはstruct list
はありますか?
GCCでは、次のように__attribute__((packed))
を使用できます。
// sizeof(x) == 8
struct x
{
char x;
int a;
};
// sizeof(y) == 5
struct y
{
char x;
int a;
} __attribute__((packed));
doc を参照してください。
また、構造体フィールドのアドレスに依存している場合は、offsetof
マクロを確認してください。たぶん、構造物を梱包する必要はまったくありません。
@Banexが触れたように
_#pragma pack(Push,1)
struct
{
char a;
int b;
long long c;
} foo;
#pragma pack(pop)
_
#pragma pack(Push,1)
は、現在のパッキングモードを内部的にプッシュし、パッキングを1に設定します。パディングはありません。
#pragma pack(pop)
は以前のパッキングを復元します
おそらくMicrosoftの構文と互換性があります
http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html
struct
内のフィールドは、実装で定義された方法で埋め込まれます。
そうは言っても、フィールドは通常、問題のデータメンバー(またはメンバーが配列の場合は配列要素)のサイズの倍数であるオフセット上に配置されます。つまり、16ビットのフィールドは2バイトのオフセットから始まり、32ビットのフィールドは4バイトのオフセットから始まります。
struct
のフィールドをこのガイドラインに準拠するように並べ替えると、通常、struct
内に内部パディングが含まれることを回避できます(ただし、末尾にパディングが生じる場合があります)。
フィールドを適切なオフセットに配置することにより、struct
を強制的にパックするよりもパフォーマンスが向上します。
詳細については、 構造パッキングに関するこの記事 を参照してください。
上記のテクニックの使用は保証されていませんが、ほとんどの場合、機能する傾向があります。