> この場合、short だから2バイト、あるいは最適化されても1バイト消費されること
に
> なるのでは…?
先にも書いたように、規格上はビットフィールドにshort型を使うことはできません。
(処理系定義の型を使うことは可能なので、short型のビットフィールドを処理系がサポ
ートしていればOKですが)
したがって、short型を使った場合の振る舞いは完全に処理系に依存します。
仮にsigned int型などを使った場合でも、ビットフィールドを格納するために十分な大
きさであれば、実際に構造体のサイズがどうなるかは処理系定義です。さらに、ビット
フィールドの連続性や、ビットフィールド割り付けの順序(MSBからかLSBからか)など
も処理系定義です。
それから、最適化の有無で構造体のサイズが変わると、翻訳単位間のバイナリ互換性が
なくなるので、普通はそのような実装は行われません。
> 先にも書いたように
あーあー何見てるんだ俺は。ゴメンナサイ。
処理系定義、っすか。
つまり処理系によっては、ビットフィールドを使ったからといって必ずしもメモリの節
約につながるとは限らない、と。
了解でした。
シャノンさんへ
>処理系定義、っすか。
>つまり処理系によっては、ビットフィールドを使ったからといって必ずしも
>メモリの節約につながるとは限らない。
根本的に勉強しなおしてから書き込んではいかがでしょうか?
たぶんまだ誤解してます
jactaさんの言葉はアセンブラを頭で展開できない人には理解し難い。
>> ただ、速度については、最近のコンパイラを評価していませんので
>> 変わらないかもしれません。
>シフト・論理演算を使って同じことを実現する場合と比べれば、速度低下は特にないは
>ずです。
>効率が悪くなるのは、ビットフィールドの値を(まじめに)取り出す場合で、符号拡張
>などの操作が入るために大きく遅いコードが展開されます。真偽の判定だけならそれほ
>ど効率は低下しません。
これはつまりビットフィールドの処理速度は確実に低下するということです。
>> 1Chipマイコンでメモリが厳しいときや、通信データなど、データ量を
>> 減らしたい場合にビット変数を使用していますが、
>1チップマイコンの場合には、RAMは確かに節約できますがROMを著しく浪費します。
ROMが増えるのはアセンブラで展開される命令コードが増えるという意味です。
つまり、処理速度は確実に低下します。
>また、制御レジスタへのアクセスにビットフィールドを使うのも色々と問題が
>あります。
Cプログラマは、レジスタのアクセスにビットフィールドを使用しちゃうのか^^;;
レジスタ系はアセンブラ命令でアクセスすることを推奨します。
>通信データの場合は確かにデータ量が減るのですが、ビットフィールドの展開の
>されかたは処理系によって大きく異なるので、厄介な問題が付いて回ります。
処理系によってintのサイズも変わりますので、インタフェースの構造体を別の処理系で
そのまま使用できると思ってもらっては困ります。
> jactaさんの言葉はアセンブラを頭で展開できない人には理解し難い。
そうかもしれませんね。
ただ、ビットフィールドのオーバーヘッドが気になるような状況では、いずれにしても
アセンブラを理解できないと話にならないと思います。
> これはつまりビットフィールドの処理速度は確実に低下するということです。
確実に低下するとまではいえません。
CPUのアーキテクチャにもよりますが、速度低下を防ぐには、ビットフィールドは必ず1
ビットにすべきで、そのまま真偽値(すなわちif等の条件式として使う)として使えば
よいのです。ビットフィールドの値を使って加算等の演算をしたり、他の変数に代入し
たりすると、とたんに速度低下が起こります。
> Cプログラマは、レジスタのアクセスにビットフィールドを使用しちゃうのか^^;;
ルネサスなどでは、制御レジスタにアクセスするためのビットフィールドを宣言したヘ
ッダを配布したりしています。純正以外のコンパイラを使うとたちまち破綻するのです
が...
> レジスタ系はアセンブラ命令でアクセスすることを推奨します。
専用のI/O命令が必要な場合か、μsec以下のオーダーで制御するような場合を除けば、必
ずしもアセンブラを使う必要はないと思います。
> 処理系によってintのサイズも変わりますので、インタフェースの構造体を別の処理系
> でそのまま使用できると思ってもらっては困ります。
データ型のサイズはまだ管理しやすいのですが、もっとやばいのはバイトオーダーや境
界調整です。(最悪の場合は1バイトのビット数まで違う)
ビットフィールドの場合はフィールド内のビットオーダーや構造体の最小サイズも違っ
てしまうので、外部とバイナリでやりとりするのはまず無理です。
その昔、ビットフィールドってのがあるから使いたいと言う話を先輩にしたら、
遅くなるからやめろって言われてその時は使うのをやめた記憶が有ります。
まあ、余計なコードが出てきそうだからなるほど遅くなるだろうなぁ
と納得していたんですが、一ビットのビットフィールドはそうでもないんですね。
移植性やらなにやら考えたらビットフィールドを使うのはやめた方がよさそうですね。
クロスプラットフォームを意識するならなおさらの事。
最近は、動作環境がリッチになってビット単位でフラグ操作をするような状況は
リソースが厳しいかぎられた環境だけになったみたいですね。
動作速度の低下についても一般に出回っているWindows用のPCで動かす限りは
目くじら立てるほどではなくなってきているだろうし。
そうなると可読性を上げるためにビットフィールドという選択肢もありかなと
思います。
メリットとデメリットに関する知識は確かに必要だと思いますけれど。
何か面白そうな話題が・・・
以前RTPを実装する作業に携わったことがありましたが、
そのときに、RTPヘッダやRTCPヘッダを定義するRFCのサンプルコードで
ビットフィールドが使われているのを見かけました。
RTPではリアルタイム性を考慮して
データ項目のサイズを必要最小に制限して、
無理やり4バイト単位のパケットデータに詰め込んでいます。
そのため、ヘッダの中では3ビット幅だの5ビット幅だのという
項目が多数定義されており、そのような項目を操作する場合には
マスクをかけて必要なビットを残す、といった操作を行うよりは、
ビットフィールドを使用したほうがはるかにわかりやすく記述になります。
もちろんそのサンプルでは、CPUのEndianの違いも考慮されていて、
ちゃんとLittle-Endian用の定義とBig-Endian用の定義が
用意されていました。
わたしはよくビットフィールドを使いますよ。って圧縮のソフトを作る時だけですけど。圧縮ソ
フトを作る時、ビット単位で少しでもファイルが小さくなるように…と、考えながら作る時、ソ
ースが見やすくなります。でも、遅くなるとは…知りませんでした。それ以外で使うことは全く
ないですね。
> その昔、ビットフィールドってのがあるから使いたいと言う話を先輩にしたら、
> 遅くなるからやめろって言われてその時は使うのをやめた記憶が有ります。
シフトやビット演算を行う時間や、コードが複雑になることを考えると、
ビットフィールド使っちゃいますね。
処理系依存になっちゃうのは、この際目をつぶっちゃいます。
#それにしても、MPEG-TSのヘッダー何とかして欲しいよー。