1

だから私はC++でプログラミングしていて、私が知る限り、stdint.hに相当するC++はありません。stdintのコピーを取得して含めることができるので、これは問題ありません...しかし、私の質問は基本的にこれです、

これら2つのコードの違いは何ですか?

struct FREQ{
    unsigned int FREQLOHI :16;
    //etc...

};

struct FREQ{
    uint16_t FREQLOHI;
    //etc...
}

ビットフィールドの明らかな制限以外に、パフォーマンス/移植性の問題はありますか?どちらが好ましいですか?

4

2 に答える 2

4

違いは、unsigned intuint16_tの16ビット幅が保証されているのに対し、プラットフォームによってサイズが異なる場合があることです。これは、最初の(ビットフィールド)構造体のインスタンスが、プラットフォームごとにサイズが異なる可能性があることを意味します。また、ビットフィールドアクセスは、余分なシフトとマスクを伴うため、より高価です。

たとえば、unsigned intが32ビット幅のラップトップでは、最初の構造体は32ビット幅で、2番目の構造体は16ビットです。

移植性に関しては、ビットフィールドは1998年に標準化されたときにC ++に含まれていた古いC言語機能であるため、はるかにクリーンな状況にあります(ISO / IEC 14882:1998)。一方、stdint.hCに追加されたのは1999年(ISO / IEC 9899:1999標準)のみであるため、C ++ 98(ISO / IEC 14882:1998)の一部ではありません。次に、対応するヘッダーcstdintがC ++ TR1に組み込まれましたが、すべての識別子がstd::tr1名前空間に配置されました。Boostもヘッダーを提供しました。最新のC++標準(2011年9月にリリースされたC ++ 11、別名ISO / IEC 14882:2011)にはヘッダーが含まれており、cstdintすべての識別子がstd名前空間に配置されます。それにもかかわらず、cstdint広くサポートされています。

于 2011-11-06T14:55:13.410 に答える
2

コンパイラは通常、ビットフィールドを1つのワードにまとめる傾向があるため、構造体の全体的なサイズが小さくなります。このパッキングは、ビットフィールドメンバーへのアクセスが遅くなるという犠牲を払っています。例えば:

struct Bitfields
{
    unsigned int eight_bit : 8;
    unsigned int sixteen_bit : 16;
    unsigned int eight_bit_2 : 8;
};

として梱包される可能性があります

0            8                        24
-----------------------------------------------------
| eight_bit  | sixteen_bit            | eight_bit_2 |
-----------------------------------------------------

アクセスするたびにsixteen_bit、シフトとビット単位の演算が発生します。

一方、あなたがそうするなら

struct NonBitfields
{
    uint8_t eight_bit;
    uint16_t sixteen_bit;
    uint8_t eight_bit_2;
};

次に、コンパイラは通常、メンバーを単語の境界に揃え、次のようにレイアウトします。

0            8           16           24
-----------------------------------------------------
| eight_bit  |            | sixteen_bit             |
-----------------------------------------------------
| eight_bit_2|                                      |
-----------------------------------------------------

これはビットフィールドと比較してより多くのスペースを浪費しますが、メンバーはビットシフトとマスキングなしでより速くアクセスできます。


その他の違いは次のとおりです。

  • sizeofビットフィールドメンバーには応募できません。
  • 参照によってビットフィールドメンバーを渡すことはできません。

移植性に関しては、どちらのオプションも標準に準拠したコンパイラで機能するはずです。構造体をファイルまたはソケットに書き出すときに異なるプラットフォーム間のバイナリ移植性を意味する場合、どちらの場合もすべての賭けは無効になります。


好みの点では、uint16_tスペースを節約するためにフィールドをまとめる正当な理由がない限り、ビットフィールドの代わりに使用することを選択します。構造体の中に多くboolのsがある場合は、通常、ビットフィールドを使用して、これらのブールフラグを同じ単語にまとめて圧縮します。

于 2011-11-06T17:06:02.227 に答える