15

VisualStudio2008を使用してWindowsXP/ Vista /7用のC++アプリケーションを作成しています。例に示すように、一部の構造体はビットフィールドを使用しています。

typedef struct myStruct_tag
{
    BYTE myVar1;
    WORD myVar2;
    WORD myVar3;
    union
    {
        struct
        {
            BYTE           :1;
            BYTE field1    :1;
            BYTE field2    :1;
            BYTE reserved  :5;
        } myBitField;
        BYTE myVar4;
    };
    BYTE myVar5;
    BYTE myVar6;
} myStruct_t;

フィールドのどちらの端が最上位ビットですか?

4

3 に答える 3

25

C99 標準 6.7.2.1/10 (強調地雷):

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

そのため、コンパイラの実装によって順序を文書化する必要があります。

ただし、ビットフィールドがどのように実装されるかについては、実装定義または未指定であるため、移植可能な方法でハードウェア、ワイヤプロトコル、またはファイル形式のビットフィールドをモデル化するためにそれらを使用することは、試行する価値がありません。

「ビットフィールド」でプログラムの外部のもの (上記のものなど) をモデル化する場合は、明示的なマスクを使用し、標準のビット単位の演算子 ( |、「& ,~ ,<<」など)を使用してビットを設定およびクリアします。 . ヘルパー インライン関数 (または必要に応じてマクロ) を使用して、コード内でこれをより簡単/明確にします。

于 2010-12-28T17:20:34.137 に答える
8

Visual Studio 2008 コンパイラ ドキュメントは次のことを示しています。

ビット フィールドとして宣言されたデータの順序は、下位ビットから上位ビットの順です。

C++ ビット フィールド」、MSDN C++ 言語リファレンス、Visual Studio 2008 バージョンから

于 2016-12-15T05:05:06.113 に答える
2

myBitField のどのビットがメモリ内のバイトのどのビットに格納されているかについて質問している場合、それは C 標準では明示的に定義されていません。実験によって学ぶ必要があります。これが実際に重要なことをしている場合は、代わりに #definefield1を 16 進値 (たとえば、0x40または0x02) として使用し、必要な場所に配置するアプローチを使用することはおそらく価値があります。

于 2010-12-28T16:31:54.683 に答える