64bit値の32bit変数への代入

warning C4244対策は、LONG_PTRをLONGに暗黙変換すると警告されるというものだが、この種の警告はいくつかあった。
64bit WindowsではLONG_PTRは64bitの整数型すなわち__int64だ。PTRという名前だからポインタかと思ったらそうではなくて、ポインタを保持できる大きさを持つという意味合いだと思われる。で、

int i;
void *p = NULL;
LONG_PTR lp = 0;
というときに、

  • i = lp; // warning C4244
  • i = (int)lp; //OK
  • i = PtrToLong(lp); // warning C2664
  • i = p; // error C2440
  • i = (int)p; // warning C4302
  • i = PtrToLong(p); //OK

という感じ。数値型の切り詰めは明示的なキャストを行えばOKだけど、ポインタの場合はキャストしても警告されるという違いがある。
なので、PtrToLongはポインタの切り詰めの場合だけに必要となる。逆に、ポインタでないものを切り詰めようとするとwarning C2664が出る。