int = int - long の危険性

int = int - long をすると、値がおかしくなるケースがあることを知ったのでその話。

 

 

例えば

intの100からlongの100億を引いた場合は、

gist5813c956cbcdcb5f6b76aeb3ff445a75

$ gcc int=int-long.c

$ ./a.out

-1410065308

 

なんだかよく分からない値が出力されます。

 

なぜなのか

16進数で値を代入してみると分かりやすいです。ちなみにintが4byte、longが8byteの環境です。

 

gist8baa74c3fe9b272abf59eab1f01be450

$ gcc anser.c

$ ./a.out

hoge : 00000000ffff00ff -65281

huga : 7fffffffffffffff 9223372036854775807

   a : 00000000ffff0100 -65280

   b : 7fffffffffff0100 9223372036854710528

 

等幅フォントじゃないのでかなり分かりにくい実行結果ですが、こういうことです。

要するにオーバーフローしてるだけなんですけど、バグらせた時になかなか気づけなさそうだったので、書きました。

 

他にもint = int - unsignedとかfloat = float - doubleとかでも同じ現象が起きるので拡大変換には気をつけようという話でした。