1

値の 3 つのペアを表す 16 ビットがあり、それぞれが 5 ビット長で、もう 1 つの 1 ビット値が正確にこの順序である場合、ビットフィールドを使用してこれを記述しても安全ですか? ANSI Cは、指定した順序でビットが正確に配置されることを保証しますか?

struct {
    unsigned v1 : 5;
    unsigned v2 : 5;
    unsigned v3 : 5;
    unsigned v4 : 1;
} test;

そうでない場合、これを表すために使用できる他のデータ構造はありますか? それともchar、移植性を確保するために、2 つの 8 ビットを格納し、プログラムで操作する必要がありますか?

4

3 に答える 3

4

私が見つけた関連する引用は、C99からの6.7.2.1(1)です:

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

unsignedこれは実際には「基になるユニット」タイプではなく、ビットフィールド宣言自体の一部にすぎないと思います。つまり、 「 nビットのタイプT : nを取る」という意味です。本当の問題は、実装が「大きな」ユニットを選択する必要があるかどうかです。たとえば、ユニットをaにすることで、 3バイトを使用できます。1つは、、1つは、、最後の1つは。または、ユニットを16ビット整数にすることもできます。その場合、1つのユニットのみを使用する必要があります。Tcharv1v2v3, v4

ただし、ご指摘のとおり、ユニット内のビットフィールドの順序は指定されていません。Cのデータのアトミック単位はアドレスであり、ビットフィールドにはアドレスがありません。構造体メンバーのアドレスは宣言順に増加することが保証されていますが、ビットフィールドについて(基礎となるユニットについてのみ)そのようなステートメントを作成することはできません。

于 2012-06-05T02:38:15.300 に答える
1

uint16_tからの型を使用できますstdint.h。これは、符号なし16ビット量の型同義語であることが保証されています。エンディアンが気になる場合は、さらに複雑になります。

于 2012-06-05T02:36:11.573 に答える
0

ビット フィールドの実装定義の側面に加えて、プラグマまたはその他のコンパイラ ディレクティブを追加して、パディング ビットを挿入しないようにコンパイラに指示する必要がある場合もあります。

これは、ビットフィールドを使用してバイト値からいくつかのビットを抽出する方法について書いたばかりの回答です。これを書いたとき、追加する必要があることがわかりまし#pragma pack(1)た。そうしないと、ビット フィールドが 1 バイトに収まりませんでした。

C の char のビットにアクセスする

unionこの回答は、データを完全なバイトまたはビット フィールドとしてアクセスできるようにするために a を使用する方法も示しています。同じ手法を使用して、短い整数またはビット フィールドとしてデータにアクセスできます。

于 2012-06-05T03:33:15.493 に答える