2005-10-21 [長年日記]

[Q3] x64版

作るだけ作っておいて放置されていたx64版ですが、実行環境が近くにあったので試してみました。

まず実行しようとすると、いきなり、

q3u.exe は有効な Win32 アプリケーションではありません。

というメッセージが…サンプルなどを作りながらコンパイルオプションを変えてテストしてみたところ、サブシステムのバージョンが間違っていました^^;つい、Windows CEのときの癖でマイナーバージョンを二桁にしてしまったため、やたら未来のバージョンになってしまっていました。

-SUBSYSTEM:WINDOWS,5.10

x64版のWindows XPは、5.2らしいので、

-SUBSYSTEM:WINDOWS,5.2

にしたら解決。ついでに、ここを参考に、_WIN32_WINNTとWINVERは0x502にしました。これを実行すると今度は、

このアプリケーションの構成が正しくないため、アプリケーションを開始できませんでした。
アプリケーションを再度インストールすることにより問題が解決する場合があります。

だそうで。このページによるとどうやらマニフェストがおかしい時に出ることがあるようです。マニフェストは手作りなので調べてみたところ、processorArchitecture=X86と自分で書いていました。ここをプラットフォームごとにわけるようにして、「AMD64」にして解決。後で気づいたのですが、「*」にしてしまうという手もあったようです。

さて、これでめでたく実行できるようになったのですが、メッセージを表示しようとするとAccess Violationで落ちてしまいます。仕方がないので、x64版のWinDbgをインストールしてデバッグしてみました。色々と追った挙句、原因はわかったのですが、今まで他のプラットフォームで発生していなかったのが不思議なくらいなものでした。

具体的には、破壊的コピーコンストラクタを持つクラスのインスタンスを渡すときの引数が、参照でなくて値渡しになっていた挙句、別の引数でそのインスタンスを参照していたというバグでした。本当はもっと複雑ですが簡略化すると、

struct X {
  X(X& x) { // 破壊的 }
  int get() const { // メンバ変数参照 }
};

void foo(X, int); // 一番目の引数は参照でなくてはいけなかった

X x;
foo(x, x.get());

というような感じでした。一番目の引数が先に評価されると、x.get()したときにはオブジェクトが既に壊れているというものです。今までのコンパイラでは、一番目の引数のコピーコンストラクタが呼び出される前にx.get()が評価されていたために問題にならなかったのではないかと思われます。

というわけで、一通り動くようになりました。HTML表示やSSLなども動いています。

[]