スレッドを立てるまでもない質問雑談スレ23

このエントリーをはてなブックマークに追加
963仕様書無しさん
こんにちわ。よろしければ教えてください。

VC6 で以下のようなことをしました。

unsigned long a = 0;
int b = 32;
int c = 0;

a = (unsigned long)( ~( ~0 << b ) << c );

実際には関数として作成していて変数 b と c の値は時々で変わります。
ここで b に 32 、c に 0 を指定すると a に 0 が代入されます。
が、ステップ実行で上式の右辺部分を選択して値を確認すると ~0 の値が表示されます。

そこで試しに以下のようにすると a に ~0 が代入されました。

a = (unsigned long)( ~( ~0 << 32 ) << 0 );

どうやら b の部分を変数で記述すると 0 が返るようです。
これはなぜなのでしょうか。ご教示頂ければ幸いです。

964仕様書無しさん:2006/04/29(土) 20:01:08
32回左シフトを指示した場合のシフト演算結果とコンパイラが計算して展開した値が違うみたい。
値はコンパイラの値が正しいけど、i386では以下の理由で32回シフト = シフトしないのと同じになる。

ttp://pdos.csail.mit.edu/6.828/2005/readings/i386/SAL.htm
To reduce the maximum execution time, the 80386 does not allow shift counts greater than 31.
If a shift count greater than 31 is attempted, only the bottom five bits of the shift count are used.

プログラムでシフト回数がレジスタ幅以上にならないようにチェックしたほうがよさそう。
(PowerPCのgccは b=32のときの ~0 << bの値が期待通り 0 になる)