2016-07-05 5 views
6

私は、ビットフィールドが移植性がないと主張しているビットフィールドに関するさまざまな質問について多くのコメントを寄せてきましたが、その理由を正確に説明するソースを見つけることはできませんでした。なぜC++のビットフィールドは移植性がありませんか?

私は、すべてのビットフィールドが同じビットシフトコードのバリエーションにコンパイルされていると推測していましたが、明らかにそれ以上のものがなければなりません。

だから私の質問は、ビットフィールドは非移植作ることが何であるかをですか?

+1

「安全でない」とはどのような状況でですか?リンクを追加しますか? – anatolyg

+6

私は、ほとんどの人がビットフィールドを悪用して、他のデータ型の表現をサブバイトレベルで抽出する方法を考えていますが、これは完全に移植性がありません。 – user2357112

+0

@anatolyg [Lundinのコメント]([http://stackoverflow.com/questions/])[http://stackoverflow.com/questions/35934375/bitfields-in-c-programming-language/35935493#comment59526628_35934375] 35934375 /ビットフィールドイン・プログラミング言語/ 35935493)。私が「携帯ではない」と同じくらい「安全でない」と非難されているのを見たことはありませんが、それでもなおあります。 – Pharap

答えて

2

ビットフィールドは、ビットの順序が指定されていないという意味で非ポータブルです。だから、コンパイラのインデックス0のビットは別のコンパイラの最後のビットになる可能性があります。

これは、メモリマップされたハードウェアレジスタ内のビットをトグルするようなアプリケーションでビットフィールドを使用することを防止します。

しかし、あなたは彼らが(例えば、マイクロチップのような)を解放コード内のハードウェア・ベンダーの利用ビットフィールドが表示されます。通常は、コンパイラをリリースするか、単一のコンパイラをターゲットにするためです。たとえば、マイクロチップの場合、ソースコードのライセンスでは、独自のコンパイラ(8ビットローエンドデバイス用)を使用する必要があります。

@Pharapが指すリンクには、(C++ 14)この未指定の順序に関連する規範:is-there-a-portable-alternative-to-c-bitfields

+2

ビットフィールドレイアウトは実装定義です。*ビットフィールドを移植不可能にしません。特定のレイアウトを想定していないコードは、移植性がありません。 – 4386427

+0

@ 4386427:ビットフィールドを使用するための一般的な理由*は、所望のレイアウトを得ることである。 OS API関数の引数のオプションビット。問題は、すべてのコンパイラが同じ結果を生成するわけではないということです(あるいは、別の方法では、標準が最も一般的なユースケースに対して合理的な保証を提供しないということです)。結局、誰かが嫌な人になったが、必ずしも元のプログラマーではない。 –

+0

@ 4386427言語構成はポータブルではなく、ポータブルではありません。これはコンパイラによってサポートされるかどうかです。移植性について言及するとき、私たちは常にこれらの構造体の*使用*について話します。私はそれを正確にする必要はないと思った。 – fjardon

8

ビットフィールドは整数が非ポータブルで同じ意味で非ポータブルです。整数を使用して移植可能なプログラムを書くことはできますが、intのバイナリ表現をそのままリモートマシンに送信し、データを正しく解釈することは期待できません。プロセッサの1ワード長が異なるため

これは、そしてそのため、整数型のサイズが異なる(1.1バイトの長さがあまりにも異なることができるが、それは、これらの日稀外部組み込みシステムです)。また、バイトエンディアンはプロセッサ間で異なるためです。

これらの問題は簡単に解決できます。ネイティブエンディアンは、合意されたエンディアン(ビッグエンディアンは事実上のネットワーク通信の標準です)に簡単に変換でき、コンパイル時にサイズを検査でき、最近では固定長の整数型が利用できます。したがって、これらの詳細が処理されている限り、整数はネットワーク経由で通信するために使用できます。

ビットフィールドは、通常の整数型の上に構築ので、彼らはエンディアンと整数サイズで同じ問題を抱えています。しかし、彼らは実装を指定したeven moreを持っています。

  • 例えばクラスオブジェクト

    • 内のビットフィールドの実際の割り当ての詳細についてのすべて、いくつかのプラットフォーム上で、ビットフィールドは、彼らが
    • 行う他人に、バイトをまたぐませんまた、一部のプラットフォームでは、ビットフィールドは、他の人に、左から右へのパックされ、右から左へ
  • かどうか茶r、short、int、long、およびlong longビットフィールドは、明示的に符号なしまたは符号なしでは符号付きまたは符号なしです。エンディアンとは異なり

、正規の形式に「実際の割り当ての詳細についてのすべてを」に変換するのは簡単ではありません。

また、endiannessはCPUアーキテクチャ固有のものですが、ビットフィールドの詳細はコンパイラ実装者固有のものです。したがって、同じ(バージョンの)コンパイラを使用してコンパイルされていることを保証できない限り、ビットフィールドは同じコンピュータ内の別々のプロセス間でも通信のために移植できません。


TL; DRビットフィールドは、コンピュータ間で通信する移植可能な方法ではありません。整数もどちらでもないが、それらの非移植性は簡単に回避できる。

関連する問題