14

この方法で、いくつかのビットを 1 バイトにパックする必要があります。

struct  
{  
  char bit0: 1;  
  char bit1: 1;  
} a;  

if( a.bit1 ) /* etc */

また:

if( a & 0x2 ) /* etc */

ソース コードの明快さから、ビットフィールドの方がすっきりしていることは明らかです。しかし、どちらのオプションがより高速ですか? 速度差はあっても大差ないのはわかっていますが、どれも使えるので速い方がいいです。
一方、ビットフィールドがプラットフォーム間で同じ順序でビットを配置することが保証されていないことを読んだので、コードを移植できるようにしたいと考えています。

注: 「プロフィール」に回答する予定がある場合は、そうしますが、私は怠け者なので、誰かがすでに回答を持っている場合は、はるかに優れています。
コードが間違っている可能性があります。必要に応じて修正できますが、この質問の要点を覚えておいて、回答してみてください。

4

7 に答える 7

12

ビットフィールドを適切に使用すると、コードがより明確になります。ビットフィールドは、省スペース デバイスとしてのみ使用します。それらが使用されているのを私が見た一般的な場所の 1 つは、コンパイラです。多くの場合、型またはシンボル情報は、一連の true/false フラグで構成されています。ここではビットフィールドが理想的です。典型的なプログラムでは、コンパイル時にこれらのノードが何千も作成されるためです。

一般的な組み込みプログラミングの仕事、つまりデバイスレジスタの読み取りと書き込みを行うためにビットフィールドを使用することはありません。ここでシフトとマスクを使用することをお勧めします。これは、ドキュメンテーションが必要としているビットを正確に取得し、ビットフィールドのさまざまなコンパイラ実装の違いを心配する必要がないためです。

速度に関しては、優れたコンパイラはマスキングと同じビットフィールドのコードを提供します。

于 2010-01-24T14:24:22.510 に答える
7

移植性を最大限に高めるために、2 番目の例を優先して使用したいと思います。Neil Butterworth が指摘したように、ビットフィールドの使用はネイティブ プロセッサ専用です。わかりました、これについて考えてみてください。Intel の x86 が明日廃業した場合、コードはスタックします。つまり、RISC チップなどの別のプロセッサ用にビットフィールドを再実装する必要があります。

全体像を見て、OpenBSD が 1 つのコードベースを使用して BSD システムを多くのプラットフォームにどのように移植したのかを尋ねる必要があります。わかりました、それは少しやりすぎであり、議論の余地があり、主観的であることは認めますが、現実的に言えば、コードを別のプラットフォームに移植したい場合は、質問で使用した2番目の例を使用してそれを行う方法です.

それだけでなく、さまざまなプラットフォームのコンパイラには、コンパイラがオンになっているプロセッサのビットフィールドを調整する独自のパディング方法があります。さらに、プロセッサのエンディアンはどうですか?

魔法の弾丸としてビットフィールドに頼らないでください。プロセッサの速度が必要で、修正する予定がある場合、つまり移植するつもりがない場合は、自由にビットフィールドを使用してください。両方を持つことはできません!

于 2010-01-24T14:54:26.407 に答える
6

C ビットフィールドは、発明された瞬間から死産でした - 理由は不明です。人々はそれらを好まず、代わりにビット演算子を使用しました。他の開発者が C ビットフィールド コードを理解していないことを想定する必要があります。

どちらが速いかに関して:関係ありません。最適化コンパイラ (実質的にすべてを意味します) は、コードがどの表記法でも同じことを行うようにします。C プログラマーは、コンパイラーが検索してキーワードをアセンブリーに置き換えるだけであると誤解しています。最新のコンパイラは、ソース コードを達成すべきものの青写真として使用し、その後、非常に異なって見えることが多いが意図した結果を達成するコードを発行します。

于 2010-01-24T14:48:28.893 に答える
5

最初のものは明示的であり、速度に関係なく、構造体を変更すると2番目の式が間違っている可能性があるため、2番目の式はエラーが発生しやすくなります。

だから最初を使う。

于 2010-01-24T14:15:34.483 に答える
4

移植性が必要な場合は、ビットフィールドを避けてください。また、特定のコードのパフォーマンスに関心がある場合は、独自のテストを作成する以外に方法はありません。ビットフィールドは、フードの下でプロセッサのビット単位の命令を使用することに注意してください。

于 2010-01-24T14:14:46.370 に答える
1

「移植性のないビットフィールド」についてはあまり読まないでください。実装で定義されるビットフィールドには、符号とレイアウトの2つの側面と、指定されていない1つの側面があります。それらがパックされているアロケーションユニットの配置です。パッキング効果以外に何も必要ない場合は、それらを使用することは、signedプロパティが指定されていない関数呼び出しと同じように移植可能です(必要に応じてキーワードを明示的に指定する必要があります)。

パフォーマンスに関しては、プロファイルが最良の答えです。完璧な世界では、2つの文章の間に違いはありません。実際には、いくつかある可能性がありますが、私は一方の方向にもう一方の方向と同じくらい多くの理由を考えることができます。そして、それは文脈に非常に敏感である可能性があります(たとえば、署名されていないものと署名されたものの論理的に無意味な違い)ので、文脈で測定してください...

要約すると、違いは、あなたが本当に選択できる場合(つまり、正確なレイアウトが重要である場合ではない場合)のほとんどの場合、スタイルの違いです。そのような場合、それは最適化(速度ではなくサイズ)であるため、最初にそれなしでコードを記述し、必要に応じて後で追加する傾向があります。したがって、ビットフィールドは当然の選択です(実行される変更は、結果を達成するための最小のものであり、すべての使用場所に広がるのではなく、一意の定義場所に含まれます)。

于 2010-01-24T15:57:24.103 に答える
1

C プログラマーは、ビット マスクと論理演算を使用して各ビットの値を推測するという 2 番目のオプションを好む傾向があると思います。コードに 16 進数値を散らかすのではなく、列挙型をセットアップするか、通常はより複雑な操作が必要な場合はマクロを使用して特定のビットを取得/設定します。構造体で実装されたビットフィールドは遅いと聞いたことがあります。

于 2010-01-24T14:15:23.450 に答える