3

ビット フィールドを持つ構造体がある場合、後続のメンバーは構造体でどのように配置されるのでしょうか? 次のコードを検討してください。

struct A{
    int a:1;
    char b;     // at offset 1
};

struct B{
    int a:16;
    int b: 17;
    char c;     // at offset 7
};

printf("Size of A: %d\n", (int)sizeof(struct A));
printf("Offset of b in A: %d\n", (int)offsetof(struct A, b));

printf("Size of B: %d\n", (int)sizeof(struct B));
printf("Offset of c in B: %d\n", (int)offsetof(struct B, c));

出力:

Size of A: 4
Offset of b in A: 1
Size of B: 8
Offset of c in B: 7

ここで、最初のケースでbは、パディングなしで構造体の 2 番目のバイトに割り当てられます。ただし、2 番目のケースでは、ビット フィールドが 4 バイトオーバーフローcすると、最後の (8 番目の) バイトに割り当てられます。

2番目のケースでは何が起こっていますか?一般に、ビットフィールドを含む構造体のパディングのルールは何ですか?

4

2 に答える 2

2

後続のメンバーは構造体でどのように配置されていますか?

誰も知らない。これは実装定義の動作であり、したがってコンパイラ固有です。

2番目のケースでは何が起こっていますか?

コンパイラによって、パディング バイトまたはパディング ビットが追加された可能性があります。または、構造体のビット順が予想と異なる場合があります。構造体の最初の項目に MSB が含まれているとは限りません。

一般に、ビットフィールドを含む構造体のパディングのルールは何ですか?

コンパイラは、構造体の最初で行われない限り、任意の種類のパディング バイト (およびビット フィールドのパディング ビット) を構造体のどこにでも自由に追加できます。

ビットフィールドは、標準では非常に不十分に定義されています。それらは、メモリ内のランダムな場所に割り当てられたブールフラグのチャンク以外には、本質的に役に立ちません。代わりに、単純な整数に対してビット単位の演算子を使用することをお勧めします。その後、100% 確定的で移植可能なコードが得られます。

于 2013-10-15T06:41:29.417 に答える