64 ビット対応2008年07月27日 22:25

 『64 ビット版 RH1FFT』
 http://cessna373.asablo.jp/blog/2008/07/27/3654881
に関連するプログラミングの話です。

64 ビット対応は、必要に応じて INT や DWORD を INT_PTR や DWORD_PTR に置き換えるのが主な作業です。
*_PTR は、64 ビットビルドでは 64 ビット、32 ビットビルドでは 32 ビットの整数としてコンパイルされます。
 『The New Data Types』
 http://msdn.microsoft.com/en-us/library/aa384264(VS.85).aspx
ANSI ビルドと UNICODE ビルド両用の TCHAR みたいなものです。

INT_PTR を INT に代入していたりすると、32 ビットでは問題ないのですが、64 ビットでは桁の切捨てが発生するので問題になることがあります。
それを 32 ビットビルドで検出するために、VisualStudio 2005 には /Wp64 (64 ビット移植性の問題の検出) オプションがあるのですが…これがいまいちです。
まず INT& 引数に INT_PTR を渡しても、INT_PTR& 引数に INT を渡しても、警告が出ません。ちょっとひどすぎますね。

さらに template <typename INT_PTR> と template <typename INT> が同じインスタンスになります。
これにより、例えば
 template <typename T>
 T Max(T lhs, T rhs)
 {
  return lhs < rhs ? rhs : lhs;
 }
のような良くあるテンプレートを定義していると、
 int main()
 {
  INT_PTR i = 0, j = 0;
  INT_PTR k = Max(i, j); // INT_PTR Max(INT_PTR, INT_PTR) のインスタンスが生成される。

  INT i2 = 0, j2 = 0;
  INT k2 = Max(i, j);  // INT_PTR Max(INT_PTR, INT_PTR) が使われる。戻り値の INT_PTR を INT に代入しているので警告。

  return 0;
 }
となったり、
 int main()
 {
  INT i = 0, j = 0;
  INT k = Max(i, j);    // INT Max(INT, INT) のインスタンスが生成される。

  INT_PTR i2 = 0, j2 = 0;
  INT_PTR k2 = Max(i, j);  // INT Max(INT, INT) が使われる。引数で INT_PTR を INT に代入しているので警告。

  return 0;
 }
となったりで、無意味な警告のオンパレードです。しかも使用する順番によって内容が変わります。

さんざん試行錯誤した末、/Wp64 オプションを使うのは止めて、単に x64 プラットフォーム用にクロスコンパイルしました。
 『方法 : Visual C++ プロジェクトを 64 ビット プラットフォーム用に設定する』
 http://msdn.microsoft.com/ja-jp/library/9yb4317s(VS.80).aspx
その結果、手許の環境では実行できない 64 ビット版ができあがったというわけです。
VisualStudio 2008 ではひょっとしたら改善されているかもしれませんが、やはり一番いいのは /Wp64 なんか使わずに、素直に 64 ビットでビルドしてみることですね。

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://cessna373.asablo.jp/blog/2008/07/27/3654901/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。