2

書いてはいけない理由を探していた

struct bitfield {
  signed foo:4;
  unsigned bar:2;
};

冗長に指定する代わりに

struct bitfield {
  signed int foo:4;   
  unsigned int bar:2; 
};

ビットフィールドの各メンバーのサイズはコロンの後に明示的に指定されているため、欠点はありますか?

charshortlong、を使用しても問題ありlong longませんか? 指定されたビットフィールドのビット数は、おそらく常に宣言型の幅よりも小さい必要がありますか?


関連する質問がいくつか見つかりました:

答えは次のとおりです。

  • int(signed/unsigned)または_Booland以外の型を使用しないでください
  • _Boolsigned intunsigned int、またはその他の実装定義型。(C99 6.2.7.1 (4) )

このコンテキストでは、この非特定の他の実装定義型はどのようなものであり、この場所での私の選択からどのような他の欠点が生じる可能性がありますか?

4

2 に答える 2

3

「時々」、「はい」

C99では、幅の式が「指定された型のオブジェクトのビット数を超えない」必要があるため、使用する型が小さすぎると、コードがコンパイルされないか、少なくとも移植性がなくなります。§6.7.2.1(3)を参照してください。

更新された3番目の質問と一般的なものに関して、「正確に結果は何ですか?」問題として、影響を受ける可能性のあるものは、移植性、位置合わせ、およびパディングです。この規格は、最初のものについてのみ明確な仕様を示しています。ビットフィールドがない場合、通常、コンパイラが最適に整列された値を生成するために何をするかを予測することに基づいて、整列とパディングを調整する可能性があります。保証はされていませんが、一部の環境では、shortなどを使用すると、結果としてアライメントとパディングが減少するため、メモリを節約できるようです。

正確なレイアウトと移植性という時折矛盾する目標を達成するための1つの可能なアプローチは、おそらく型を使用して、ビットフィールドなしでメモリ内データ構造を宣言すること<stdint.h>です。次に、ビットフィールドを使用して何かをデコードする場合は、メモリ内のソースオブジェクトを、ビットフィールドとビット固有の型の和集合である一時変数に割り当てるか、またはをキャストして型のパンニング規則に故意に違反します。ポインタ。(Linuxはこれをいたるところに行っています。)

より良い方法は、おそらくビットフィールドを避けることです。

于 2012-04-22T19:43:02.227 に答える
2

コードの両方のバージョンで、幅は明示的です。符号付きと符号なしの幅ですintsignedはの単なるエイリアスでintあり、。も同様ですsigned int。同様にunsigned、はのエイリアスですunsigned int。孤独signedでありunsigned、修飾子ではなく、それ自体が名前を入力します。

于 2012-04-22T19:24:20.550 に答える