32ビット環境ではSetWindowLongPtrはSetWindowLongのエイリアスになります。それとは別に、VCのデフォルトでは /Wp64 オプションが有効になっています。これは64ビットOSへの移植性が損なわれる場合に警告を出すと言うもので、
void* p = &p; unsigned long i = (unsigned long)p; // C4311
上記のようなキャストをする際に警告(C4311)を出してくれるというもの。64ビット環境ではポインタは64ビットになるので、32ビットのlong型にキャストするのはまずいよ、と言ってくれます。
どちらもそれだけで見ればどうということないものなのですが(むしろ警告は便利)、SetWindowLongの第三引数はlong型なので、こいつにポインタを渡す場合longにキャストする必要があり、そこで警告が出てしまいます。SetWindowLongPtrであれば問題ないのですが、前述の通り32ビット環境ではSetWindowLongPtr==SetWindowLongなので、どちらを使っても警告が出てしまいます。
/Wp64を無効にするのは簡単だけれども、それはなんだか負けた気がするので、少し調べてみました。
- Bugslayer: Optimize and Trim Your Code with New Switches in Visual C++ .NET
- The resource cannot be found.
Bugslayerにはpragmaで警告を無効にするよう書いてあるけれど、下のブログのコメントにもっとよさげなコードが。
# re: SetWindowLongPtr and /Wp64
Billy
Posted @ 3/12/2007 11:03 AM
SetWindowLongPtr(0, 0, (__int3264)(LONG_PTR)x);It took me forever to figure that out...
__int3264とはビルド環境によって、int32もしくはint64になるものらしい。これを利用することで、どちらの環境でも警告を出すことなくビルドできるそうな。素晴らしい! ということでこれを利用することにしました。それにしても__int3264なんてあやしげな(ソース見れば一目瞭然ですけれど)マクロもあるんですね。奥が深いというかなんというか。