私は長い間、Cにビットフィールドがあることを知っていましたが、密集した構造体を定義するためにそれらを使用することがあります。
typedef struct Message_s {
unsigned int flag : 1;
unsigned int channel : 4;
unsigned int signal : 11;
} Message;
オープンソースコードを読むと、代わりに、手で巻いたビットフィールドにそのような情報を格納および取得するためのビットマスクおよびビットシフト操作を見つけることがよくあります。これは非常に一般的であるため、作成者はビットフィールドの構文を認識していなかったと思います。したがって、コンパイラに依存して生成するのではなく、ビットマスクを介してビットフィールドをロールし、操作を独自にシフトする理由があるのではないかと思います。このようなビットフィールドを取得および設定するためのコード。
他のプログラマーがビットフィールドの代わりに手書きのビット操作を使用して複数のフィールドを1つの単語にパックするのはなぜですか?
質問は非常にオープンであるため、この回答は意見に基づいています。
多くのプログラマーは、ビットフィールドの可用性に気付いていないか、それらの移植性と正確なセマンティクスについて確信がありません。正しいコードを生成するコンパイラの能力を信用しない人さえいます。彼らは理解できる明示的なコードを書くことを好みます。
Cornstalksがコメントしているように、この態度は実際の経験に根ざしています この記事で説明されているように 。
ビットフィールド構造体を避ける理由はありますか?
ビットフィールド構造体にはいくつかの制限があります。
scanf()
を使用)およびビットフィールドでのポインターの使用はできません。sizeof()
はビットではなくバイトで結果を生成するため、sizeof()
演算子をビットフィールドに適用することはできません。したがって、それらを使用する必要があるかどうかは異なります。続きを読む ビットエンディアンがビットフィールドで問題になるのはなぜですか?
その理由はありません。ビットフィールドは便利で便利です。それらは組み込みプロジェクトで一般的に使用されています。一部のアーキテクチャ(ARMなど)には、ビットフィールドを操作するための特別な命令さえあります。
コードを比較するだけです(そして関数foo1の残りを書きます) https://godbolt.org/g/72b3vY
多くの場合、Word内のビットの個々のグループをアドレス指定できること、またはWordを1つの単位として操作できると便利です。この規格は現在、そのような機能を実現するための実用的でポータブルな方法を提供していません。コードがビットフィールドを使用するように記述されていて、後で複数のグループにWordとしてアクセスする必要が生じた場合、ビットフィールドを使用してすべてのコードを作り直すか、型のパンニングを使用して型ベースのエイリアシング最適化を無効にすることなく、それに対応する良い方法はありません。そして、すべてが期待どおりにレイアウトされることを願っています。
シフトとマスクの使用はエレガントではないかもしれませんが、Cが明示的に指定されたある左辺値内のビットのシーケンスを別の左辺値として扱う手段を提供するまで、コードが適応可能であることを保証する最良の方法であることがよくありますニーズを満たすために。