下記のように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;

このQ&Aに関連する最新のQ&A

A 回答 (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というような
期待をした処理が無ければ移植性は失われません。
    • good
    • 0
この回答へのお礼

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

お礼日時:2002/03/27 17:23

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と定義すると、そのような場合に
不都合が起こるということです。

この回答への補足

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


よろしければ回答をお願いします。

補足日時:2001/10/25 10:42
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
なるほど移植性を考えてということなのですね。
 
>long型のビット数はOSが変われば変わるので

確かにそうですね。
(~0L)としている意味がわかりました。

お礼日時:2001/10/25 10:42

「~」は、1の補数演算子です。


0Lはlong型で表すので、32bitです。(マシンによって異なる場合あり)
0を32bitの2進数で表すと 00000000000000000000000000000000(0が32個)となるので、
~0は 11111111111111111111111111111111(1が32個)となります。
10進数で表すと、signed long型なら -1、unsigned long型なら 4294967295 となります。
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/10/25 10:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

QAES暗号にて、AES_set_encrypt_keyで設定されるAES_KEYについて

VC++2008にてopensslを用いて、AES暗号/復号の機能を作成しています。

AES_set_encrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_ENCRYPT)にて暗号、
AES_set_decrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_DECRYPT)にて復号するコーディングをしました。

(http://d.hatena.ne.jp/hnko/20090302/1235977892のenc_aes128_cbc_test()を参考にしましたので、
一連の流れは、こことほぼ同じです)

デバッグしてみると、一見、暗復号が問題なく出来ていたので、
AES_set_encrypt_key関数の第一引数のkey配列の値と、
ivec配列の値を変えて、デバッグしてみたところ、
key配列を変更すると、暗号化後の文字列も変更されますが、
ivec配列を変更しても、暗号後の文字列に変化が有りませんでした。

調べてみたところ、AES_set_encrypt_keyにて返される
AES_KEYのroundsの値が常に同じであることが原因と思われますが、
roundsの値が常に一定だと、暗号解読が比較的容易に
出来てしまうと思うのですが、上記で挙げたサイトでの
コーディングの他に、何か別にコーディングを足さなければならないのでしょうか?

よろしくお願いします。

VC++2008にてopensslを用いて、AES暗号/復号の機能を作成しています。

AES_set_encrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_ENCRYPT)にて暗号、
AES_set_decrypt_key → ivをコピー → AES_cbc_encrypt(~,AES_DECRYPT)にて復号するコーディングをしました。

(http://d.hatena.ne.jp/hnko/20090302/1235977892のenc_aes128_cbc_test()を参考にしましたので、
一連の流れは、こことほぼ同じです)

デバッグしてみると、一見、暗復号が問題なく出来ていたので、
AES_set_encrypt_key関数の第一引...続きを読む

Aベストアンサー

>ivec配列を変更しても、暗号後の文字列に変化が有りませんでした。
初期ベクタを変えれば必ず暗号文が変化する筈。
変わらないとしたら、初期ベクタを変えているつもりで変わってないだけ。

因みに、初期ベクタは、1ブロック暗号化するたびに内容が更新されていくので、使い方を間違えないように。

>roundsの値が常に一定だと、暗号解読が比較的容易に
暗号鍵を変えればAES_KEYの内容も変化する筈。
変わらないとしたら、暗号鍵を変えているつもりで変わってないだけ。

QVisual Studioで ユニコード "~" が0xff5eと解釈されるが0x301cと解釈してもらいたい。

Visual Studioで ユニコード "~" が0xff5eと解釈されるが0x301cと解釈してもらいたいのですが可能でしょうか?
プログラム中で置き換えるしかないのでしょうか?
そうなると全ての文字に対して0xff5eか調べなくてはならず嫌なのですが。

Aベストアンサー

 前回の補足です。
 windowsはシフトJISの世界です。そして、シフトJISには全角チルダは存在しません。あるのは波ダッシュのみです。ところが、波ダッシュをwindowsの世界でユニコード変換すると全角チルダのコードに変換されてしまいます。キーボードから0x301cに対応する文字を入力する方法はわかりませんが、IMEパッドの文字一覧から0x301cに対応する波ダッシュは入力できます。しかし期待通りに動作するかはわかりません。

なんか上手く説明できなくてごめんなさい。

QhDC=::GetDC(m_hWnd)とhDC=GetDC(m_hWn

hDC=::GetDC(m_hWnd)とhDC=GetDC(m_hWnd)の違いについて

表題について,お伺いします。
ビットマップをダイアログに表示するソースコードを
書いてますが,参考書やさまざまなHPでは,
ウィンドウハンドルをゲットする際に

hDC=::GetDC(m_hWnd) ○
↑と書かれております。

hDC=GetDC(m_hWnd)  ×
↑はなぜだめなのでしょう。

 ●このスコープ演算子::は何の為につけているのですか?

::が無いとエラーになるので必要みたいですが・・

Aベストアンサー

どういうエラー(リンクエラー、コンパイルエラー)なのかがわからないので、
あくまで憶測ですが、
Windows.hで定義されているGetDC()の他に、
別のスコープに(例えばクラスのメソッドとして)、
GetDC()が定義されているのではないでしょうか?

上記の状態でスコープ演算子がないときには、
同じクラス(スコープ)にあるGetDC()を先に呼ぶことになるので、
目的のWindows.hのGetDC()を呼ぶことができないのだと思います。

参考URL:http://wisdom.sakura.ne.jp/programming/cpp/cpp7.html

Qdc.TextOut(0 ,0 , *str) ;について

環境 WIN98 VC++6.0 MFC にて

パターンBはOKですが、パターンAだと不正な処理で落ちてしまいます。

どうしてなのかお教えください。

void CFffView::OnPaint()
{
CPaintDC dc(this);
//パターンA
CString* str ;
str = (CString*)("999");
dc.TextOut(0 ,0 , *str) ;

//パターンB
CString aaa ;
aaa = (CString)("999");
dc.TextOut(0 ,0 , aaa) ;
}

Aベストアンサー

両方ダメ。
Aのパターンで動くのは、たまたま。

CString aaa ;
aaa = "999";
dc.TextOut(0 ,0 , aaa) ;

これで十分。

あえてキャストするんだったら、
CString aaa ;
aaa = (LPCSTR)"999";
dc.TextOut(0 ,0 , aaa) ;


aaa=のところでは、ただの代入が行われているわけではありません。
オーバーロードされたオペレータが呼ばれています。


>str = (CString*)m_array.GetAt(i) ;

これは、m_arrayの要素にCString*を入れていて、初めて成り立つ式です。
値をいれているところと、m_arrayの宣言を確認してください。

str = (CString*)("999");
も、
aaa = (CString)("999");
も、リテラル文字列をつっこもうとしています。
リテラル文字列とCStringはまったく別物です。


人気Q&Aランキング

おすすめ情報