int x = 0xffffffff; x <<= 32; x = ?
int main(){ int x = 0xffffffff; x <<= 32; printf("%x\n",x); }
実行結果
ffffffff
ってきり0になるものだと思いこんでて少しはまりました…
(この場合gccはちゃんと warning: left shift count >= width of type と警告出してくれます)
なんでこうなるかというとCの規格ではシフト演算するとき左辺のビット幅よりも大きいシフト量を指定したときの動作は未定義とのことです*1. で,intelのIA-32デベロッパーズマニュアル*2にはシフト量は5ビットにマスクされて0-31の値に制限される,と書いてありました (char 型の変数を8ビット左シフトしたらちゃんと0になりました).8086だとマスクをしてなかったけれど,IA-32は全てシフトカウントを5ビットにマスクするので*3シフトカウントが最大31ビットに制限される一方,その分命令の最大実行時間が減らせるとのことです.
まぁ冷静に考えてみるとシフト演算はマルチプレクサで構成されてるんだろうからシフト幅が0-31で32パターンだったら選択信号5ビットあれば選択できる(2^5=32)のでこうなってるんでしょうね.ちなみに8086は1ビットシフトを繰り返してたみたいですね.
*1:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf の6.5.7に書いてあります.
*2:2-B 198ページ目
*3:仮想8086モードの場合でも