3

私は次の構造を持っています:

struct bf_struct1
{
    uint64_t bf1 : 1;
    uint64_t bf2 : 6;
    uint64_t bf3 : 2;
    uint64_t bf4 : 55;
}

struct bf_struct2
{
    uint8_t bf1 : 1;
    uint8_t bf2 : 6;
    uint8_t bf3 : 2;
    uint64_t bf4 : 55;
}

構造体メンバーのアラインメントは、ビットフィールド メンバーの型に依存しますか?

4

5 に答える 5

2
#include <stdio.h>

#define uint64_t unsigned long long
#define uint8_t unsigned char

struct bf_struct1
{
    uint64_t bf1 : 1;
    uint64_t bf2 : 6;
    uint64_t bf3 : 2;
    uint64_t bf4 : 55;
};

struct bf_struct2
{
    uint8_t bf1 : 1;
    uint8_t bf2 : 6;
    uint8_t bf3 : 2;
    uint64_t bf4 : 55;
};
int main(){
    printf("%lu ", sizeof(struct bf_struct1));
    printf("%lu ", sizeof(struct bf_struct2));
    return 0;
}

結果は 8 16 です。したがって、答えはイエスです。私のマシンでは gcc と clang が一致していても、コンパイラに依存します。いくつかのユニオンを作成して、アライメントが何であるかを正確に把握できます。

于 2013-10-09T15:00:49.283 に答える
2
  • ビット フィールド全体のアラインメントは未規定の動作であり、ビット フィールドがアラインされていない割り当てを許可されるかどうかは実装定義の動作です。
  • ビット フィールドのビット順序は実装定義です。
  • 上記の 2 つの注意事項により、コンパイラは実装定義の方法で、必要に応じて、ビット フィールド内の任意の場所にパディング ビットとパディング バイトを自由に追加できます。
  • uint64_t が実際にビット フィールド内で許可されるかどうかは、実装によって定義されます。そのため、コードが機能しない場合もあります。

特定のコンパイラのドキュメントを読まずに、このコードが何をするのか、ましてやアラインメントがどのように影響するのかを知る方法はありません。

于 2013-10-09T15:25:48.743 に答える
1

馬の口から:

6.7.2.1 構造体および共用体指定子
...
5 ビットフィールドは、 の修飾バージョンまたは非修飾バージョン、またはその他の実装定義の型である型を持たなければならない。アトミック型が許可されるかどうかは実装定義です。 ..._Bool, signed int, unsigned int

11 実装では、ビットフィールドを保持するのに十分な大きさのアドレス指定可能なストレージユニットを割り当てることができます。十分なスペースが残っている場合、構造内の別のビットフィールドの直後に続くビットフィールドは、同じユニットの隣接するビットにパックされます。十分なスペースが残っていない場合、収まらないビットフィールドを次のユニットに配置するか、隣接するユニットとオーバーラップするかは実装定義です。ユニット内のビットフィールドの割り当て順序 (上位から下位、または下位から上位) は実装定義です。アドレス可能なストレージ ユニットのアラインメントは指定されていません。

簡単な答え: 実装によっては可能です。

于 2013-10-09T17:40:18.930 に答える
1

はい、影響する可能性があります。最初の例では、すべてのフィールドが 1 つの 64 ビットに収まるuint64-tため、構造体は合計 8 バイトになる可能性があります。ただし、2 番目の場合、合計で 16 バイトになる可能性があります。最初の 3 つのフィールドには、少なくとも 2 バイト (2 uint8_t) が必要です。次に、55 ビットの最後のビット フィールドはuint64_t、8 バイト境界に配置される可能性が高いシングルを取得します。したがって、実際のレイアウトはコンパイラに依存しますが、ビットの位置は両方の例で異なります ( uint64_t2 番目の例では、前にパディングが想定されているためです。

レイアウトは次のようになります (正確な縮尺ではありません)。

bf_struct1

+---------------+---------+---------+-----------------------------------+
|    uint8_t    | uint8_t | Padding | uint64_t                          |
+---------------+---------+---------+-----------------------------------+
| bf1, bf2, bf3           | 48-bits | bf4                               |
+---------------+---------+---------+-----------------------------------+

bf_struct2

+-----------------------------------+
|      uint64_t                     |
+-----------------------------------+
| bf1, bf2, bf3, bf4                |
+-----------------------------------+
于 2013-10-09T15:00:26.350 に答える