web-dev-qa-db-ja.com

構造体内のパディングを無効にするようにgccに指示する方法は?

それが正常なのかコンパイラのバグなのかわかりませんが、多くのメンバーを持つ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.

私のプログラムが機能していない理由を見つけるのに苦労しましたが、ようやく見つかりましたhltiの間に2バイトのギャップがありますこれは0x0に設定されています。これは、iが整列していることを意味します。
構造体のその部分を印刷すると、これは非常に明確です。

for(int i=28;i<35;i++)
    printf("%02hhX",buf[i]);

画面にEBF40000EB90EB90が表示されます。

プログラムでvolatile struct list data;などを試しましたが、配置の問題は変わりませんでした。

#pragmatype内でiを整列しないようにgccに指示する__attribute__またはstruct listはありますか?

6
user2284570

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マクロを確認してください。たぶん、構造物を梱包する必要はまったくありません。

23
Oleg Andriyanov

@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

5
infixed

struct内のフィールドは、実装で定義された方法で埋め込まれます。

そうは言っても、フィールドは通常、問題のデータメンバー(またはメンバーが配列の場合は配列要素)のサイズの倍数であるオフセット上に配置されます。つまり、16ビットのフィールドは2バイトのオフセットから始まり、32ビットのフィールドは4バイトのオフセットから始まります。

structのフィールドをこのガイドラインに準拠するように並べ替えると、通常、struct内に内部パディングが含まれることを回避できます(ただし、末尾にパディングが生じる場合があります)。

フィールドを適切なオフセットに配置することにより、structを強制的にパックするよりもパフォーマンスが向上します。

詳細については、 構造パッキングに関するこの記事 を参照してください。

上記のテクニックの使用は保証されていませんが、ほとんどの場合、機能する傾向があります。

2
dbush