• ベストアンサー

補数(~)について

下記のようにenumの中で、(~0L) という記述があります。 これは反転して、「RE_SET_ALL=1」となるのですか? また、直値を入れるのではなく、(~0L)としているメリットは あるのでしょうか? /* E:SetOff */ typedef enum { RD_SET_ALL = (~0L), RD_SET_OFF = -1, RD_SET_DEL = -2, RD_BYTE_OFF = 0xff } RdeSetOff;

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

>(~0L)は移植性を考えてということは良く分かりました。 >では他の変数に(RD_SET_OFF = -1等)は、直値を入れてますが、 >これは移植性がないのではないでしょうか? 「~0」は0に対して1の補数をとるので、全てのビットが1に成ります。 「-1」は多くの処理系では1に対して2の補数を取るので、 全てのビットが1に成りますが、全ての処理系で負の数に2の補数が 使われているわけではないので、 全てのビットが1に成っていることを期待するプログラムは良くないわけです。 しかし、「-1」を内部のビット表現に依存しない形で(単に-1として)使う分 には問題ないわけです。 多分、プログラム中でも、RD_SET_OFFやRD_SET_DELは、どのビットが0で どのビットが1かを気にする使い方はしてないと思いますが。 なので、 >(enumの中には4変数定義されてますが、その他の変数(0L以外)に >移植性がなければ意味がなくなりませんか?) RD_SET_OFFがAllビット1、RD_SET_DELがLSBが0で残りは1というような 期待をした処理が無ければ移植性は失われません。

korei
質問者

お礼

回答ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (2)

  • Fooky
  • ベストアンサー率71% (59/82)
回答No.2

finalanswerさんが全て答えられてますが、 補足です。 > また、直値を入れるのではなく、(~0L)としているメリットは > あるのでしょうか? これの答えはまさしく、 > マシンによって異なる場合あり です。移植性を確保するためにはプリミティブな 表現はできるだけ避けるべきです。 例えば、現在の時刻を秒数で表す変数型time_typeが、 typedef unsigned long time_type; と表されている(time_type = unsigned long)、 ということを知っていたとしても、プログラム中で time_typeの代わりにunsigned longを使うのは 避けるべきです。 もし、unsigned longで現在の時刻を表しきれない 事態が発生して、 typedef unsigned long long time_type; と、time_type型が定義し直された場合、 time_type型を使っているのなら、コンパイルし直す だけで済みますが、unsigned longをそのまま使って いたとすると、ソースコード中で、time_typeの意味で 使っていたunsigned longを全てunsinged long longに 書きなおさなければなりません。 これと同じ事で、あなたの環境ではlong型で全ての ビットが立っていると4294967295になるかも知れませんが、 他のOSでは全てのビットが立っているlong型の数値は 全く別の値になるかもしれません。 別の言い方をすると、このプログラムでは、RD_SET_ALLが 4294967295であることが重要なのではなく、RD_SET_ALLが ビットが全て立ったlong型であることが重要である、という ことです。で、long型のビット数はOSが変われば変わるので、 RD_SET_ALLを4294967295と定義すると、そのような場合に 不都合が起こるということです。

korei
質問者

お礼

回答ありがとうございます。 なるほど移植性を考えてということなのですね。   >long型のビット数はOSが変われば変わるので 確かにそうですね。 (~0L)としている意味がわかりました。

korei
質問者

補足

(~0L)は移植性を考えてということは良く分かりました。 では他の変数に(RD_SET_OFF = -1等)は、直値を入れてますが、 これは移植性がないのではないでしょうか? (enumの中には4変数定義されてますが、その他の変数(0L以外)に 移植性がなければ意味がなくなりませんか?) よろしければ回答をお願いします。

すると、全ての回答が全文表示されます。
回答No.1

「~」は、1の補数演算子です。 0Lはlong型で表すので、32bitです。(マシンによって異なる場合あり) 0を32bitの2進数で表すと 00000000000000000000000000000000(0が32個)となるので、 ~0は 11111111111111111111111111111111(1が32個)となります。 10進数で表すと、signed long型なら -1、unsigned long型なら 4294967295 となります。

korei
質問者

お礼

「~0L」の意味はわかりました。 ありがとうございます。

すると、全ての回答が全文表示されます。

関連するQ&A