クイズ
突然ですが問題です。以下のプログラムをx86_64アーキテクチャ(64bit)上で動かした場合の実行結果はどうなるでしょうか?
#include <stdio.h>
int main(int argc, char *argv[]) {
unsigned long code = -1UL;
printf("code = %016lx\n", code);
printf("code >> 16 = %016lx\n", code >> 16);
printf("code >> 63 = %016lx\n", code >> 63);
printf("code >> 64 = %016lx\n", code >> 64);
printf("code >> 65 = %016lx\n", code >> 65);
return 0;
}回答は以下の通り。
(反転させて見てください)
[kaigai@masu ~]$ ./a.out code = ffffffffffffffff code >> 16 = 0000ffffffffffff code >> 63 = 0000000000000001 code >> 64 = ffffffffffffffff code >> 65 = 7fffffffffffffff
こりゃ驚いた。別に x86_64 に限った話ではなく、i386でも同様に、シフト演算子を使う時のシフト幅は sizeof(変数) * 8 でモジュロ演算した結果に落とされてしまう。
これを知らなかったせいで、x86_64では以下のコードが無限ループに落ちてしまった。うーむ、深い。
unsigned long maps[];
u64 bitmap;
while (bitmap) {
maps[index++] |= bitmap & (-1UL);
bitmap = bitmap >> BITS_PER_LONG;
}ちなみにどうやって解決したか。
while (bitmap) {
maps[index++] |= bitmap & (-1UL);
bitmap = ((bitmap >> BITS_PER_LONG/2)
>> BITS_PER_LONG/2);
}これでいいのだ。