web-dev-qa-db-ja.com

ビットフィールド構造体のメンバーを避ける理由はありますか?

私は長い間、Cにビットフィールドがあることを知っていましたが、密集した構造体を定義するためにそれらを使用することがあります。

typedef struct Message_s {
     unsigned int flag : 1;
     unsigned int channel : 4;
     unsigned int signal : 11;
} Message;

オープンソースコードを読むと、代わりに、手で巻いたビットフィールドにそのような情報を格納および取得するためのビットマスクおよびビットシフト操作を見つけることがよくあります。これは非常に一般的であるため、作成者はビットフィールドの構文を認識していなかったと思います。したがって、コンパイラに依存して生成するのではなく、ビットマスクを介してビットフィールドをロールし、操作を独自にシフトする理由があるのではないかと思います。このようなビットフィールドを取得および設定するためのコード。

19
wirrbel

他のプログラマーがビットフィールドの代わりに手書きのビット操作を使用して複数のフィールドを1つの単語にパックするのはなぜですか?

質問は非常にオープンであるため、この回答は意見に基づいています。

  • 多くのプログラマーは、ビットフィールドの可用性に気付いていないか、それらの移植性と正確なセマンティクスについて確信がありません。正しいコードを生成するコンパイラの能力を信用しない人さえいます。彼らは理解できる明示的なコードを書くことを好みます。

    Cornstalksがコメントしているように、この態度は実際の経験に根ざしています この記事で説明されているように

  • ビットフィールドの実際のメモリレイアウトは実装によって定義されます。メモリレイアウトが正確な仕様に従う必要がある場合は、ビットフィールドを使用しないでください。手動でコード化されたビット操作が必要になる場合があります。
  • 符号付き型付きビットフィールドでの符号付き値の処理は、実装で定義されています。符号付きの値がビットの範囲にパックされている場合は、アクセス関数を手動でコーディングする方が信頼性が高い場合があります。
15
chqrlie

ビットフィールド構造体を避ける理由はありますか?

ビットフィールド構造体にはいくつかの制限があります。

  1. ビットフィールドは、移植性のないコードになります。また、ビットフィールド長はワードサイズに大きく依存します。
  2. アドレス指定ができないため、読み取り(scanf()を使用)およびビットフィールドでのポインターの使用はできません。
  3. ビットフィールドは、より多くの変数をより小さなデータスペースにパックするために使用されますが、コンパイラーはこれらの変数を操作するための追加のコードを生成します。これにより、空間と時間の両方の複雑さが増します。
  4. sizeof()はビットではなくバイトで結果を生成するため、sizeof()演算子をビットフィールドに適用することはできません。

ソース

したがって、それらを使用する必要があるかどうかは異なります。続きを読む ビットエンディアンがビットフィールドで問題になるのはなぜですか?


PS: Cでビットフィールドを使用するのはいつですか?

8
gsamaras

その理由はありません。ビットフィールドは便利で便利です。それらは組み込みプロジェクトで一般的に使用されています。一部のアーキテクチャ(ARMなど)には、ビットフィールドを操作するための特別な命令さえあります。

コードを比較するだけです(そして関数foo1の残りを書きます) https://godbolt.org/g/72b3vY

4
P__J__

多くの場合、Word内のビットの個々のグループをアドレス指定できること、またはWordを1つの単位として操作できると便利です。この規格は現在、そのような機能を実現するための実用的でポータブルな方法を提供していません。コードがビットフィールドを使用するように記述されていて、後で複数のグループにWordとしてアクセスする必要が生じた場合、ビットフィールドを使用してすべてのコードを作り直すか、型のパンニングを使用して型ベースのエイリアシング最適化を無効にすることなく、それに対応する良い方法はありません。そして、すべてが期待どおりにレイアウトされることを願っています。

シフトとマスクの使用はエレガントではないかもしれませんが、Cが明示的に指定されたある左辺値内のビットのシーケンスを別の左辺値として扱う手段を提供するまで、コードが適応可能であることを保証する最良の方法であることがよくありますニーズを満たすために。

0
supercat