web-dev-qa-db-ja.com

プログラムの64ビットバージョンを作成するのが難しいのはなぜですか。

私の短時間のプログラミングでは、プログラムの完全なソースがある限り、32ビットまたは64ビットのマシン用にC++やJavaなどをコンパイルすることは簡単です。

しかし、多くのソフトウェアは64ビットでリリースされていません。最も厄介なことに、Unityエンジンの64ビットリリースはまだありません。

一部のプログラムを64ビットマシン用にコンパイルすることが難しいのはなぜですか。

29
calben

一般的な問題は、プログラム化されていない仮定をプログラムでエンコードするのが非常に簡単であり、それらの仮定が行われた場所を見つけるのが非常に難しいことです。高水準言語はこれらの懸念からいくらか隔離する傾向がありますが、プラットフォームとサービスの実装に使用される低水準言語では、アーキテクチャ間で必ずしも移植可能ではないことを簡単に実行できます。

  • intがポインタを格納するのに十分な大きさであると仮定します

  • pointer tagging など、ポインターの表現のプロパティを想定

  • データポインターとコードポインターが同じサイズであると仮定

リリース管理の実際的な懸念もあります。私がx86ビルドのみを作成した場合でも、レジスターの可用性が制限されているためにおそらくより遅くなりますが、x86-64で実行されます。一方、x86とx86-64の両方でビルドする場合は、両方のアーキテクチャでテストし、1つのアーキテクチャでのみ発生する可能性があるバグに対処する必要があるため、新しいリリースの出荷コストが増加します。

61
Jon Purdy

32ビットと64ビットの両方のIntel/AMDアーキテクチャ用にコンパイルした場合、ほとんどのソフトウェアは同じように動作します。ただし、一部のソフトウェアはそうしません。怠惰、またはより多くの視聴者にリーチすることを除いて、64ビットとして再コンパイルが機能しない理由はいくつかあります。

  • ソフトウェアは安全でないポインタ操作を使用する場合があります。おそらく、プログラムはポインターをintに入れます。これは、ほとんどのCおよびC++コンパイラーでは一般に32ビットです。ポインターは、64ビットプログラムでは64ビットです。それは機能しません。

  • 使用されている整数型のサイズが異なる場合、ビットシフト操作は異なる結果を生成する可能性があります。これは、int32_tなどの標準のtypedefではなく、通常のデータ型を使用するときに問題になる場合があります。

  • 共用体で使用されるデータ型はサイズを変更し、共用体の動作を変更する場合があります。

  • ソフトウェアは、32ビットのみのライブラリに依存する場合があります。一般に、64ビットプログラムは、スタックやポインタなどに関する想定のため、64ビットライブラリでのみ機能します。

質問で尋ねる難しさは、一部のコードベースでは、安全でない操作を実行したり、安全でない仮定をしたり、ショートカットや開発者による巧妙な「最適化」を行ったりする数百万行のコードが存在する可能性があるということです。コードは64ビット環境でコンパイルされないか、コンパイルされますが、show-stopperバグがあります。すべての問題の修正には時間がかかる場合があります。たぶん企業は、64ビットバージョンをリリースできるようになるまで、時間をかけて修正するでしょう。完全な書き直しが必要なため、現在のメンテナンスリリースとともに「バージョン2」を開発する企業もあるでしょう。

この話の教訓は、クリーンなコードを記述し、コンパイラを推測したり、不要な賢い最適化を追加したりせずに、ソフトウェアを壊してしまい、おそらく役に立たないことです。

この記事では、この回答に含めたいと思っていたよりもはるかに詳しく説明します。 64ビットプラットフォームでのC++コードの移植に関する20の問題

26
user22815