Visual C++コンパイラで使用できる__w64キーワードの効能を確認してみました。
以下、Visual Studio .NET 2003を使うという前提で説明を行います。
もし、内容に問題等を発見された場合は、ぜひご教示下さい。
概要 §
32bit時代から64bit時代の過渡期に当たる現在、32bit用として開発したソースコードを64bitシステム用に転用するケースも少なくないと考えられます。
その際、システムの自然なサイズに一致するデータ型と、特定のビットサイズに固定されるデータ型を混用すると思わぬトラブルが起こる可能性があります。
このようなトラブルを、32bitコンパイラを使用している段階で検出するために__w64キーワードが用意されています。
__w64キーワードが付加されたデータ型は、32bitシステムでは32bitの値を持つものとして扱われますが、コンパイル時に仮に64bitの値を持つものと仮定した整合性のチェックも行われます。
__w64キーワードを使用したサンプルソース §
(ヘッダファイルの詳細略)
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int a;
__w64 int b = 10;
a = b; // warning C4244: '=' : '__w64 int' から 'int' に変換しました。データが失われているかもしれません。
return 0;
}
解説 §
サンプルソースは、a=b;の行で警告が発生します。
変数aは、普通の32bit整数値を持ち、特に特別なことはありません。
変数bは、__w64キーワードが付加されているために、実際には32bit値であるにも関わらず、それが64bit値であると仮定した整合性のチェックが行われます。その結果、64bit値を32bitの変数に代入しているという警告を発しています。
注意点 §
__w64キーワードは32bitコンパイラで使った場合にのみ意味があります。
64bitコンパイラでは、意味がないようです。
そのため、実際に__w64キーワードを使う際には、コンパイラのビット数を判定してデータ型の定義を切り替えるような定義が要求されるようです。
MSDNから引用した定義の一例を以下に示します。
#ifdef _WIN64
typedef __int64 Int_Native;
#else
typedef int __w64 Int_Native;
#endif
この定義は、Int_Nativeという型を、32bitシステムでは32bitに、64bitシステムでは64bitに設定し、かつ、32bitコンパイラでコンパイル時に64bitでの整合性のチェックを実行させることができます。
有効性の切り替え §
コマンドラインオプションの場合: /Wp64
IDEの場合: プロジェクトのプロパティ→[C/C++]→[全般]→[64 ビット移植への対応]
余談・なぜこの知識が必要であるのか §
16bit時代の以下のような何の変哲もないコードが警告を発して、どうしてもその正確な理由が把握できなかったので、思わず調べてしまいました。おかげで仕事もストップ……。とはいえ、__w64をgoogleで検索すると日本語情報は3件しか見つからず、その意味を解説しているページは皆無だったので、これを書いたことで少しは世の中に貢献すると思いたい……。
このコードは、intではなくINT_PTRを使う必要があります。DialogBoxの戻り値がINT_PTR型で、この型の定義は__w64を含むためです。