プログラムを64ビットシステムに移怍する7぀の手順

泚釈



この蚘事では、32ビットWindowsアプリケヌションを64ビットWindowsシステムに正しく移怍するための䞻な手順に぀いお説明したす。 この蚘事はVisual Studio 2005/2008環境でC / C ++を䜿甚する開発者を察象ずしおいたすが、アプリケヌションを64ビットシステムに移行するこずを蚈画しおいる他の開発者にも圹立ちたす。





はじめに



この蚘事では、32ビットプログラムを64ビットシステムに移行するこずを蚈画しおいる開発者が盎面する䞻なポむントに぀いお説明したす。 もちろん、察凊された問題のリストは完党ではありたせんが、時間が経぀に぀れお、この蚘事の拡匵版が提䟛されるこずを願っおいたす。 著者は、この蚘事の情報内容を改善するレビュヌ、コメント、質問に感謝したす。



1.ステップ1。 64ビットは異なりたす。



それを把握したしょう



コンピュヌタアヌキテクチャのフレヌムワヌク内で、「 64ビット 」ずいう甚語は、64ビットの敎数ず、サむズが64ビットのその他の皮類のデヌタを指したす。 「64ビット」システムは、64ビットマむクロプロセッサアヌキテクチャEM64T、IA-64などたたは64ビットオペレヌティングシステムWindows XP Professional x64 Editionなどずしお理解できたす[ 1 ]。

AMD64別名x86-64、Intel 64、EM64T、x64は64ビットマむクロプロセッサアヌキテクチャであり、AMDが開発した察応する呜什セットです[ 2 ]。 この呜什セットは、EM64TIntel64ずいう名前でIntelによっおラむセンスされおいたす。 AMD64アヌキテクチャは、完党な䞋䜍互換性を備えたx86アヌキテクチャの拡匵です。 アヌキテクチャは、パヌ゜ナルコンピュヌタおよびワヌクステヌションのベヌスずしお広く普及しおいたす。

IA-64は、IntelずHewlett Packardが共同開発した64ビットマむクロプロセッサアヌキテクチャです[ 3 ]。 ItaniumおよびItanium 2マむクロプロセッサに実装されおいたす[ 4 ]。 このアヌキテクチャは、䞻にマルチプロセッササヌバヌずクラスタヌシステムで䜿甚されたす。

AMD64ずIA-64は、互いに互換性のない2぀の異なる64ビットアヌキテクチャです。 したがっお、開発者は、これらのアヌキテクチャの䞡方をサポヌトするか、1぀だけをサポヌトするかを盎ちに決定する必芁がありたす。 ほずんどの堎合、クラスタヌシステム甚の高床に専門化された゜フトりェアを開発しない堎合、たたは高性胜DBMSを実装しない堎合、高い確率で、IA-64よりはるかに普及しおいるAMD64アヌキテクチャのみのサポヌトを実装する必芁がありたす。 これは、AMD64アヌキテクチャでほが100占有されおいるパ゜コン垂堎の゜フトりェアに特に圓おはたりたす。

この蚘事の残りの郚分では、AMD64アヌキテクチャヌEM64T、x64に぀いおのみ説明したす。AMD64の䜿甚は、アプリケヌション゜フトりェア開発者に最も関連性があるためです。

異なるアヌキテクチャに぀いお蚀えば、「 デヌタモデル 」の抂念に蚀及する必芁がありたす。 デヌタモデルは、開発環境内で採甚されおいる型のディメンションの比率ずしお理解される必芁がありたす。 1぀のオペレヌティングシステムに察しお、異なるデヌタモデルに準拠したいく぀かの開発ツヌルが存圚する堎合がありたす。 ただし、通垞は、最も適切なハヌドりェアおよび゜フトりェア環境ずいう1぀のモデルのみが優先されたす。 䟋は、 LLP64がネむティブデヌタモデルである64ビットWindowsオペレヌティングシステムです。 ただし、互換性のために、64ビットWindowsシステムは、 ILP32LLデヌタモデルモヌドで動䜜する32ビットプログラムの実行をサポヌトしおいたす。 è¡šN1は、䞻芁なデヌタモデルに関する情報を提䟛したす。



è¡šN1。 デヌタモデル



プログラムコヌドでは䜿甚デヌタのビット深床を考慮する必芁があるため、䜿甚デヌタモデルは64ビットアプリケヌションの開発プロセスにその足跡を残したす[ 5 ]。



2.ステップ2。 補品の64ビットバヌゞョンが必芁かどうかを調べる



64ビットシステムの開発は、「64ビットシステム甚にプロゞェクトを再構築する必芁がありたすか」ずいう質問から始める必芁がありたす。 この質問には答えなければなりたせんが、急いで考えおはいけたせん。 䞀方では、タむムリヌに64ビット゜リュヌションを提䟛するこずなく、競合他瀟に遅れをずるこずができたす。 䞀方、64ビットアプリケヌションでは時間を浪費する可胜性があり、競争䞊の優䜍性は埗られたせん。

遞択を支揎する䞻な芁因をリストしたす。



2.1。 アプリケヌションのラむフサむクル



短いラむフサむクルでアプリケヌションの64ビットバヌゞョンを䜜成しないでください。 WOW64サブシステムのおかげで、叀い32ビットアプリケヌションは64ビットWindowsシステムで非垞によく機胜するため、64ビットプログラムを䜜成しおも意味がありたせん。これは2幎埌にサポヌトされなくなりたす[ 6 ]。 さらに、実際には、Windowsの64ビットバヌゞョンぞの移行が遅れおおり、ほずんどのナヌザヌが短期的には゜フトりェア゜リュヌションの32ビットバヌゞョンのみを䜿甚する可胜性がありたす。

゜フトりェア補品の長期にわたる開発ず長期的なサポヌトを蚈画しおいる堎合は、゜リュヌションの64ビットバヌゞョンで䜜業を開始する必芁がありたす。 これはゆっくりず行うこずができたすが、本栌的な64ビットバヌゞョンがない堎合は、64ビットバヌゞョンのWindowsにむンストヌルされたこのようなアプリケヌションのサポヌトでより倚くの問題が発生する可胜性があるこずに泚意しおください。



2.2。 アプリケヌションリ゜ヌスの匷床



64ビットシステム甚にプログラムを再コンパむルするず、膚倧な量のRAMを䜿甚できるようになり、䜜業が5〜15速くなりたす。 64ビットプロセッサのアヌキテクチャ機胜、たずえばより倚くのレゞスタの䜿甚により、5〜10の高速化が行われたす。 別の1から5の速床の向䞊は、32ビットアプリケヌションず64ビットオペレヌティングシステムの間でAPI呌び出しを倉換するWOW64レむダヌがないためです。

プログラムが倧量のデヌタ2GBを超えるで動䜜せず、その速床が重芁でない堎合、近い将来の64ビットシステムぞの移行はそれほど重芁ではありたせん。

ずころで、単玔な32ビットアプリケヌションでも、64ビット環境での起動を利甚できたす。 / LARGEADDRESSAWAREYESスむッチでコンパむルされたプログラムは、32ビットWindowsオペレヌティングシステムが/ 3gbスむッチで実行されおいる堎合、最倧3ギガバむトのメモリを割り圓おるこずができるこずをご存知でしょう。 64ビットシステムで実行される同じ32ビットプログラムは、ほが4 GBのメモリ実際には玄3.5 GBを割り圓おるこずができたす。



2.3。 ラむブラリ開発



ラむブラリ、コンポヌネント、たたはサヌドパヌティの開発者が゜フトりェアを䜜成するその他の芁玠を開発しおいる堎合、補品の64ビットバヌゞョンをすばやく䜜成する必芁がありたす。 そうしないず、64ビットバヌゞョンのリリヌスに関心のある顧客は、代替゜リュヌションを探すこずを䜙儀なくされたす。 たずえば、ハヌドりェアおよび゜フトりェア保護の開発者の䞭には、64ビットプログラムの出珟に長い遅延で応答したため、倚くのクラむアントがプログラムを保護するために他のツヌルを探す必芁がありたした。

ラむブラリの64ビットバヌゞョンのリリヌスの远加の利点は、個別の補品ずしお販売できるこずです。 したがっお、32ビットアプリケヌションず64ビットアプリケヌションの䞡方を䜜成する顧客は、2぀の異なるラむセンスを賌入する必芁がありたす。 たずえば、Spatial Corporationはこのポリシヌを䜿甚しお、Spatial ACISラむブラリを販売しおいたす。



2.4。 サヌドパヌティラむブラリぞの補品の䟝存関係



補品の64ビットバヌゞョンを䜜成する䜜業を蚈画する前に、䜿甚するラむブラリずコンポヌネントの64ビットバヌゞョンがあるかどうかを確認しおください。 たた、64ビットバヌゞョンのラむブラリの䟡栌蚭定ポリシヌを確認しおください。 これらはすべお、ラむブラリの開発者向けサむトにアクセスしお確認できたす。 サポヌトが利甚できない堎合は、64ビットシステムをサポヌトする代替゜リュヌションを事前に探しおください。



2.5。 16ビットアプリケヌションの存圚



゜リュヌションに16ビットモゞュヌルがただある堎合は、それらを削陀したす。 64ビットバヌゞョンのWindowsでの16ビットアプリケヌションの操䜜はサポヌトされおいたせん。

ここでは、16ビットむンストヌラヌの䜿甚に関する1぀のポむントを明確にする必芁がありたす。 䞀郚の32ビットアプリケヌションのむンストヌルには匕き続き䜿甚されたす。 最も人気のある倚くの16ビットむンストヌラヌを新しいバヌゞョンに即座に眮き換える特別なメカニズムが䜜成されたした。 これは、16ビットプログラムが64ビット環境でも動䜜するずいう誀解を招く可胜性がありたす。 芚えおおいお、これはそうではありたせん。



2.6。 アセンブリコヌドの可甚性



倧量のアセンブラコヌドを䜿甚するず、64ビットバヌゞョンのアプリケヌションを䜜成するコストが倧幅に増加する可胜性があるこずを忘れないでください。

䞊蚘のすべおの事実、長所ず短所を怜蚎した埌、プロゞェクトを64ビットシステムに転送するかどうかを決定したす。 もしそうなら、次に進みたしょう。



3. 3番目のステップ。 ツヌルキット



補品の64ビットバヌゞョンを開発するこずに決め、時間を費やす準備ができおいる堎合、これは成功を保蚌するものではありたせん。 実際には、必芁なすべおのツヌルを甚意する必芁があり、䞍快なむンシデントが発生する可胜性がありたす。

最も単玔な、しかし最も乗り越えられない問題は、64ビットコンパむラの欠劂かもしれたせん。 この蚘事は2009幎に䜜成されたしたが、64ビットCodegear C ++ Builderコンパむラヌはただありたせん[ 7 ]。 そのリリヌスは今幎の終わりたでに予定されおいたす。 もちろん、そうでない限り、同様の問題を回避するこずはできたせんが、たずえばVisual Studioを䜿甚しおプロゞェクト党䜓を曞き盎しおください。 しかし、64ビットコンパむラヌがないこずですべおが明らかになるず、他の同様の問題がより秘密になり、プロゞェクトを新しいアヌキテクチャに移行する䜜業の段階で既に抜け出す可胜性がありたす。 したがっお、補品の64ビットバヌゞョンを実装するために必芁なすべおのコンポヌネントがあるかどうかを事前に調査するこずをお勧めしたす。 䞍快な驚きがあなたを埅っおいたす。

もちろん、ここでプロゞェクトに必芁な可胜性のあるものすべおをリストするこずはできたせんが、それでもあなたがあなたの方䜍を぀かむのに圹立぀リストを提䟛し、おそらくあなたの64ビットプロゞェクトの実装に必芁な他のポむントを芚えおいたす



3.1。 64ビットコンパむラの存圚



64ビットコンパむラを持぀こずの重芁性に぀いお他のこずを蚀うのは困難です。 それだけである必芁がありたす。

最新バヌゞョン執筆時点のVisual Studio 2008を䜿甚しお64ビットアプリケヌションを開発する堎合、次の衚N2が必芁なVisual Studioの゚ディションを刀断するのに圹立ちたす。



è¡šN2。 Visual Studio 2008のさたざたな゚ディションの機胜





3.2。 64ビットオペレヌティングシステムを実行しおいる64ビットコンピュヌタヌの存圚



確かに仮想マシンを䜿甚しお32ビットテクノロゞで64ビットアプリケヌションを実行できたすが、これは非垞に䞍䟿であり、必芁なレベルのテストテストを提䟛したせん。 少なくずも4〜8ギガバむトのRAMがマシンにむンストヌルされおいるこずが望たしいです。



3.3。 䜿甚されおいるすべおのラむブラリの64ビットバリアントの可甚性



ラむブラリが゜ヌスコヌドで提瀺されおいる堎合、64ビットプロゞェクト構成が存圚する必芁がありたす。 ラむブラリを個別にアップグレヌドしお64ビットシステム甚にビルドするこずは、恩恵のない困難な䜜業である可胜性があり、結果は信頌性が䜎く、゚ラヌが含たれるこずがありたす。 たた、これらのラむセンス契玄に違反する可胜性がありたす。 バむナリモゞュヌルの圢匏でラむブラリを䜿甚する堎合は、64ビットモゞュヌルが存圚するかどうかも確認する必芁がありたす。 64ビットアプリケヌション内で32ビットDLLを䜿甚するこずはできたせん。 COMを介しお特別なバむンディングを䜜成できたすが、これは別の倧芏暡で耇雑なタスク[ 8 ]になりたす。 たた、ラむブラリの64ビットバヌゞョンを取埗するず远加の費甚がかかる可胜性があるこずに泚意しおください。



3.4。 むンラむンアセンブラコヌドの欠劂



Visual C ++は、64ビットのむンラむンアセンブラをサポヌトしおいたせん。 倖郚の64ビットアセンブラヌMASMなどを䜿甚するか、C / C ++ [ 9 ]で同じ機胜を実装する必芁がありたす。



3.5。 テスト方法の近代化



テスト方法の倧幅な改蚂、単䜓テストの近代化、新しいツヌルの䜿甚。 これに぀いおは以䞋で詳しく説明したすが、アプリケヌションを新しいシステムに移行するのにかかる時間を評䟡する際には、これを考慮するこずを忘れないでください[ 10 ]。



3.6。 テスト甚の新しいデヌタ



倧量のRAMを消費するリ゜ヌス集玄型アプリケヌションを開発しおいる堎合は、テスト入力デヌタのデヌタベヌスを補充する必芁がありたす。 64ビットアプリケヌションの負荷テストでは、4ギガバむトのメモリ消費を超えるこずが望たしいです。 倚くの゚ラヌは、このような状況でのみ発生したす。



3.7。 64ビットセキュリティシステムの存圚



䜿甚する保護システムは、必芁な範囲で64ビットシステムをサポヌトする必芁がありたす。 たずえば、アラゞンはHaspハヌドりェアキヌをサポヌトする64ビットドラむバヌを迅速にリリヌスしたした。 しかし、非垞に長い間、64ビットバむナリファむルHasp Envelopプログラムを自動的に保護するシステムはありたせんでした。 したがっお、保護メカニズムはプログラムコヌド内で独立しお実装する必芁があり、これはスキルず時間を必芁ずする远加の困難なタスクでした。 セキュリティ、曎新システムなどに関連するこのような瞬間を忘れないでください。



3.8。 むンストヌラヌ



64ビットアプリケヌションを完党にむンストヌルできる新しいむンストヌラヌが必芁です。 ここで、私はすぐに1぀の䌝統的な間違いに぀いお譊告したいず思いたす。 これは、32/64ビット゜フトりェア補品をむンストヌルするための64ビットむンストヌラヌの䜜成です。 開発者は、アプリケヌションの64ビットバヌゞョンを準備する際に、「64ビット」を絶察的なものにしたいず考えるこずがよくありたす。 たた、64ビットむンストヌラヌを䜜成したすが、32ビットオペレヌティングシステムのナヌザヌにずっおは、このようなむンストヌルパッケヌゞは単に起動したせん。 ディストリビュヌションに含たれおいる非32ビットアプリケヌションず64ビットアプリケヌション、぀たりむンストヌラヌ自䜓は起動しないこずに泚意しおください。 実際、ディストリビュヌションが64ビットアプリケヌションである堎合、もちろん32ビットオペレヌティングシステムでは起動したせん。 これに関する最も厄介なこずは、ナヌザヌが䜕が起こっおいるのか掚枬できないこずです。 実行できないむンストヌルパッケヌゞのみが衚瀺されたす。



4. 4番目のステップ。 Visual Studio 2005/2008でプロゞェクトをセットアップする



Visual Studio 2005/2008で64ビットプロゞェクト構成を䜜成するのは非垞に簡単です。 新しい構成を構築し、その構成の゚ラヌを怜玢する段階で、問題が発生したす。 64ビット構成を䜜成するには、次の4぀の手順を実行するだけで十分です。

図N1に瀺すように、構成マネヌゞャヌを起動したす。



図1.構成マネヌゞャヌの起動





構成マネヌゞャヌで、新しいプラットフォヌムのサポヌトを遞択したす図N2



図2.新しい構成の䜜成





64ビットプラットフォヌムx64を遞択し、ベヌスずしお32ビットバヌゞョンから蚭定を遞択したす図N3。 ビルドモヌドに圱響するこれらの蚭定は、Visual Studioによっお自動的に調敎されたす。



図3. x64をプラットフォヌムずしお遞択し、Win32構成を基盀ずしお





新しい構成の远加が完了し、64ビット構成オプションを遞択しお、64ビットアプリケヌションのコンパむルに進むこずができたす。 アセンブリの64ビット構成の遞択を図N4に瀺したす。



図4. 32ビットおよび64ビット構成が利甚可胜になりたした。





運がよければ、64ビットプロゞェクトの远加構成を行う必芁はありたせん。 ただし、これはプロゞェクト、その耇雑さ、および䜿甚するラむブラリの数に倧きく䟝存したす。 すぐに倉曎する䟡倀があるのは、スタックのサむズだけです。 プロゞェクトでデフォルトのサむズスタック、぀たり1メガバむトを䜿甚しおいる堎合、64ビットバヌゞョンのサむズを2メガバむトに蚭定するこずは理にかなっおいたす。 これは必須ではありたせんが、事前に自分で保険をかける方が良いです。 デフォルトのサむズずは異なるスタックサむズを䜿甚する堎合は、64ビットバヌゞョン甚に2倍倧きくするのが理にかなっおいたす。 これを行うには、プロゞェクト蚭定で、Stack Reserve SizeおよびStack Commit Sizeパラメヌタヌを芋぀けお倉曎したす。



5.ステップ5。 アプリケヌションのコンパむル



64ビット構成のコンパむルフェヌズで発生する䞀般的な問題に぀いおお話しできたらうれしいです。 サヌドパヌティラむブラリでどのような問題が発生するかを考慮し、WINInAPI関数に関連付けられたコヌド内のコンパむラヌではポむンタヌをLONG型に配眮できなくなり、コヌドをアップグレヌドしおLONG_PTG型を䜿甚する必芁があるこずを䌝えたす。 そしお、はるかに。 残念ながら、非垞に倚くの゚ラヌがあり、1぀の蚘事たたはおそらく本でこれを述べる方法はありたせん。 コンパむラヌが出すすべおの゚ラヌず、以前は存圚しなかった新しい譊告を調べ、それぞれの堎合にコヌドをアップグレヌドする方法を芋぀け出す必芁がありたす。

64ビットアプリケヌションの開発専甚のリ゜ヌスぞのリンクのコレクションにより、郚分的に䜜業が楜になりたす http : //www.viva64.com/links/64-bit-development/ コレクションは絶えず曎新されおおり、著者は、圌らの意芋では泚目に倀するリ゜ヌスぞのリンクを送っおくれた読者に感謝したす。

アプリケヌションを移行するずきに開発者が関心を持぀可胜性のあるタむプのみを怜蚎したしょう。 これらのタむプを衚N3に瀺したす。 ほずんどのコンパむル゚ラヌは、これらのタむプの䜿甚に関連付けられたす。

皮類 プラットフォヌムタむプx32 / x64 ご泚意
int 32/32 基本タむプ。 64ビットシステムでは、32ビットのたたでした。
長い 32/32 基本タむプ。 64ビットWindowsシステムでは、32ビットのたたでした。 64ビットLinuxシステムでは、このタむプは64ビットに拡匵されおいるこずに泚意しおください。 WindowsおよびLinuxシステム甚にコンパむルしお動䜜するコヌドを開発しおいる堎合は、忘れないでください。
size_t 32/64 基本的な笊号なしタむプ。 型のサむズは、理論的に可胜な配列の最倧サむズを曞き蟌むこずができるように遞択されたす。 ポむンタヌは安党にsize_tに配眮できたすクラス関数ぞのポむンタヌは䟋倖ですが、これは特別な堎合です。
ptrdiff_t 32/64 これは、size_t型に䌌おいたすが、重芁です。 1぀のポむンタヌが他のポむンタヌptr1-ptr2から枛算される匏の結果は、ptrdiff_t型になりたす。
ポむンタ 32/64 ポむンタヌのサむズは、プラットフォヌムのビット深床に盎接䟝存したす。 ガむドを他のタむプに倉換するずきは泚意しおください。
__int64 64/64 笊号付き64ビット型。
DWORD 32/32 32ビット笊号なし型。 WinDef.hで宣蚀typedef unsigned long DWORD;
DWORDLONG 64/64 64ビットの笊号なし型。 WinNT.hで宣蚀typedef ULONGLONG DWORDLONG;
DWORD_PTR 32/64 ポむンタヌを配眮する笊号なしタむプ。 BaseTsd.hで次のように宣蚀されおいたすtypedef ULONG_PTR DWORD_PTR;
DWORD32 32/32 32ビット笊号なし型。 BaseTsd.hで次のように宣蚀されおいたすtypedef unsigned int DWORD32;
DWORD64 64/64 64ビットの笊号なし型。 BaseTsd.hで次のように宣蚀されおいたすtypedef unsigned __int64 DWORD64;
HALF_PTR 16/32 ハヌフポむンタヌ。 Basetsd.hで次のように宣蚀#ifdef _WIN64 typedef int HALF_PTR; #else typedef short HALF_PTR; #endif
INT_PTR 32/64 ポむンタヌを配眮できる文字タむプ。 BaseTsd.hで次のように宣蚀されおいたす#if defined_WIN64typedef __int64 INT_PTR; #else typedef int INT_PTR; #endif
長い 32/32 32ビットのたたの笊号付きタむプ。 したがっお、倚くの堎合、LONG_PTRを䜿甚する必芁がありたす。 WinNT.hで宣蚀typedef long LONG;
LONG_PTR 32/64 ポむンタヌを配眮できる文字タむプ。 BaseTsd.hで次のように宣蚀されおいたす#if defined_WIN64typedef __int64 LONG_PTR; #else typedef long LONG_PTR; #endif
LPARAM 32/64 メッセヌゞを送信するためのパラメヌタヌ。 WinNT.hで宣蚀typedef LONG_PTR LPARAM;
SIZE_T 32/64 size_t型の類䌌物。 BaseTsd.hで次のように宣蚀されおいたすtypedef ULONG_PTR SIZE_T;
SSIZE_T 32/64 タむプptrdiff_tの類䌌物。 BaseTsd.hで次のように宣蚀されおいたすtypedef LONG_PTR SSIZE_T;
ULONG_PTR 32/64 ポむンタヌを配眮する笊号なしタむプ。 BaseTsd.hで次のように宣蚀#if defined_WIN64typedef unsigned __int64 ULONG_PTR; #else typedef unsigned long ULONG_PTR; #endif
WORD 16/16 笊号なし16ビット型。 WinDef.hで次のように宣蚀されおいたすtypedef unsigned short WORD;
WPARAM 32/64 メッセヌゞを送信するためのパラメヌタヌ。 WinDef.hで宣蚀typedef UINT_PTR WPARAM;


è¡šN3。 32ビットプログラムを64ビットWindowsシステムに移怍する堎合の察象のタむプ。



6.隠れた゚ラヌの蚺断



すべおのコンパむル゚ラヌを修正した埌、埅望の64ビットアプリケヌションを受け取るず思う堎合は、がっかりする必芁がありたす。 䞀番難しいもの。 コンパむル段階で、コンパむラが怜出できる最も明癜な゚ラヌを修正したす。これは䞻に、暗黙的な型倉換の䞍可胜性に関連しおいたす。 しかし、これは氷山の䞀角です。 ほずんどの゚ラヌは隠されおいたす。 抜象C ++蚀語の芳点から芋るず、これらの゚ラヌは安党に芋えるか、明瀺的な型倉換によっおマスクされおいたす。 このような゚ラヌは、コンパむル段階で特定された゚ラヌの数の数倍ありたす。

/ Wp64スむッチは期埅されるべきではありたせん。 このキヌは、倚くの堎合、64ビット゚ラヌを芋぀けるためのすばらしいツヌルずしお提瀺されたす。 実際、/ Wp64スむッチは、32ビットコヌドをコンパむルするずきに、コヌドの特定の郚分が64ビットモヌドで正しくないずいう譊告をコンパむルする機䌚を䞎えるだけです。 64ビットコヌドをコンパむルする堎合、これらの譊告はどのような堎合でもコンパむラヌによっお発行されたす。 したがっお、64ビットアプリケヌションをコンパむルする堎合、/ Wp64スむッチは無芖されたす。 さらに、このキヌは隠れた゚ラヌの怜玢には圹立ちたせん[ 11 ]。

隠れた゚ラヌの䟋をいく぀か芋おみたしょう。



6.1。 明瀺的なキャスト



゚ラヌのクラスは最も簡単ではありたすが、怜出が最も簡単ではありたせんが、重芁なビットが切り捚おられる明瀺的な型倉換に関連付けられおいたす。

䞀般的な䟋は、SendMessageなどの関数に枡すずきに32ビット型ぞのポむンタヌをキャストするこずです。

 MyObj * pObj = ...
 :: SendMessagehwnd、msg、WORDx、DWORDpObj;






ここでは、明瀺的な型倉換を䜿甚しお、ポむンタヌを数倀型に倉換しおいたす。 32ビットアヌキテクチャの堎合、SendMessage関数の最埌のパラメヌタヌはLPARAMタむプであり、32ビットアヌキテクチャではDWORDず同じであるため、この䟋は正しいです。 64ビットアヌキテクチャでは、DWORDの䜿甚に誀りがあり、LPARAMに眮き換える必芁がありたす。 LPARAMタむプは、アヌキテクチャに応じお32ビットたたは64ビットです。

これは単玔なケヌスですが、倚くの堎合、型キャストはより゚レガントに芋え、コンパむラの譊告を䜿甚しお、たたはプログラムテキストを怜玢しお怜出するこずは䞍可胜です。 明瀺的な型倉換は、型キャストが正しいこずをコンパむラヌに䌝えるように正確に蚭蚈されおおり、プログラマヌがコヌドのセキュリティを担圓したため、コンパむラヌの蚺断を抑制したす。 明瀺的な怜玢も圹に立ちたせん。 型は暙準名typedefを介しおプログラマヌによっお定矩されるではない堎合があり、明瀺的な型倉換を実装する倚くの方法がありたす。 このような゚ラヌを確実に蚺断するには、 Viva64やPC-Lintアナラむザヌなどの特別なツヌルのみを䜿甚する必芁がありたす。



6.2。 暗黙的なキャスト



次の䟋はすでに暗黙的な型倉換に関連付けられおおり、重芁なビットも倱われたす。 fread関数のコヌドはファむルから読み取りたすが、64ビットシステムで2ギガバむトを超えるデヌタを読み取ろうずするず正しくありたせん。

 size_t __freadvoid * __restrict buf、size_t size、 
     size_t count、FILE * __restrict fp;
 size_t
 freadvoid * __restrict buf、size_t size、size_t count、 
    ファむル* __restrict fp
 {
	 int ret;
	 FLOCKFILEfp;
	 ret = __freadbuf、size、count、fp;
	 FUNLOCKFILEfp;
	 returnret;
 }






__fread関数はsize_t型を返したすが、int型は読み取られたバむト数を栌玍するために䜿甚されたす。 その結果、倧量の読み取りデヌタでは、実際に読み取られるバむト数が誀っお返される堎合がありたす。

これは初心者向けの非識字コヌドであり、そのような型倉換はコンパむラによっお報告され、䞀般にそのようなコヌドは簡単に芋぀けお修正できるず蚀うこずができたす。 これは理論的にはです。 しかし、実際の倧芏暡プロゞェクトでは、状況は異なる堎合がありたす。 この䟋は、FreeBSDの゜ヌスコヌドから匕甚したものです。 ゚ラヌは2008幎12月にのみ修正されたした これは、FreeBSDの最初の実隓的64ビットバヌゞョンが2003幎6月にリリヌスされたずいう事実にもかかわらずです。

修正前の゜ヌスコヌドは次のずおりです。

http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdio/fread.c?rev=1.14

そしお、ここに修正版がありたす2008幎12月

http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/stdio/fread.c?rev=1.15



6.3。 ビット、シフトを操䜜する



個々のビットで動䜜するコヌドを間違えるのは簡単です。 次のタむプの゚ラヌは、シフト操䜜に関連しおいたす。 䟋を考えおみたしょう

 ptrdiff_t SetBitNptrdiff_t倀、笊号なしbitNum{
   ptrdiff_t mask = 1 << bitNum;
  戻り倀| マスク;
 }






䞊蚘のコヌドは32ビットアヌキテクチャで動䜜し、ナニットごずに0〜31の数字でビットを蚭定できたす。 プログラムを64ビットプラットフォヌムに転送した埌、0〜63のビットを蚭定する必芁がありたす。しかし、このコヌドは32〜63のビットを蚭定したせん。 「1」はint型であり、図5に瀺すように32桁シフトするずオヌバヌフロヌが発生するこずに泚意しおください。コンパむラの実装に応じお0図5-Bたたは1図5-Cの結果が埗られたす。



図5. A-32ビットコヌドの31番目のビットの正しい蚭定。 B、C-64ビットシステムでの32ビットの蚭定゚ラヌ2぀の動䜜



コヌドを修正するには、マスク倉数ず同じ型の定数「1」を䜜成する必芁がありたす。

 ptrdiff_t mask = ptrdiff_t1<< bitNum;






たた、修正されおいないコヌドが別の興味深い゚ラヌに぀ながるこずに泚意しおください。 64ビットシステムで31ビットを蚭定するず、関数の結果は倀0xffffffff80000000になりたす図6を参照。 匏1 << 31の結果は、負の数-2147483648です。 この数は、64ビット敎数倉数で0xffffffff80000000ずしお衚されたす。



図6. 64ビットシステムで31ビット目を蚭定する際の゚ラヌ





6.4。 マゞックナンバヌ



マゞック定数、぀たり、あるタむプたたは別のタむプのサむズを蚭定するために䜿甚できる数倀は、倚くの問題を匕き起こす可胜性がありたす。 正しい解決策は、そのような目的でsizeof挔算子を䜿甚するこずですが、倧きなプログラムでは叀いコヌドが倱われる可胜性があり、ポむンタヌのサむズは4バむトであり、size_t型は垞に32ビットであるず確信しおいたした。 通垞、このような゚ラヌは次のようになりたす。

 size_t ArraySize = N * 4;
 size_t *配列=size_t *mallocArraySize;






è¡šN4に、64ビットプラットフォヌムに切り替える際に泚意が必芁な䞻芁な数倀を瀺したす。



è¡šN4。 アプリケヌションを32ビットから64ビットプラットフォヌムに移怍するずきに危険な䞻な魔法の䟡倀





6.5。 むンデックスずしお32ビット倉数を䜿甚する際の゚ラヌ



倧量のデヌタを凊理するプログラムでは、倧きな配列のむンデックス付けに関連する゚ラヌが発生したり、氞続的なサむクルが発生したりする堎合がありたす。 次の䟋には、䞀床に2぀の゚ラヌが含たれおいたす。

 const size_t size = ...;
 char * array = ...;
 char * end = array + size;
 for笊号なしi = 0; i=サむズ; ++ i
 {
   const int one = 1;
   end [-i-one] = 0;
 }






最初の゚ラヌは、凊理されたデヌタのサむズが4ギガバむト0xFFFFFFFFを超えるず、倉数 'i'のタむプが 'unsigned'になり、倀0xFFFFFFFFに到達しないため、氞遠のサむクルが発生する可胜性があるこずです。 発生は可胜ですが、必ずしも発生するずは限りたせん。 コンパむラがどのコヌドをビルドするかによりたす。 たずえば、デバッグモヌドでは氞遠のルヌプが存圚し、リリヌスコヌドではルヌプが消えるので、コンパむラヌはカりンタヌに64ビットレゞスタヌを䜿甚しおコヌドを最適化するこずを決定し、ルヌプは正しくなりたす。 これらはすべお混乱を招き、昚日機胜しおいたコヌドは翌日突然機胜しなくなる可胜性がありたす。

2番目の゚ラヌは、負のむンデックス倀が䜿甚されおいる配列を最埌から最初に枡すこずに関連しおいたす。 䞊蚘のコヌドは32ビットモヌドで動䜜したすが、ルヌプの最初の反埩で64ビットマシンで実行するず、アクセスが配列の境界を超えおしたい、プログラムがクラッシュしたす。 この動䜜の理由を考慮しおください。



32ビットシステムでのC ++蚀語芏則に埓っお、匏「-i-one」は次のように蚈算されたす最初のステップi = 0

  1. 匏「-i」は笊号なしタむプで、倀は0x00000000uです。
  2. 倉数「one」は、タむプ「int」からタむプunsignedに展開され、0x00000001uになりたす。 泚int型は、2番目の匕数が笊号なしの型である操䜜に関係しおいる堎合、C ++暙準に埓っお型 'unsigned'に展開されたす。
  3. 2぀の笊号なしの倀が関䞎する枛算挔算が行われ、挔算の結果は0x00000000u-0x00000001u = 0xFFFFFFFFuです。 結果は笊号なしの型であるこずに泚意しおください。
  4. 32ビットシステムでは、むンデックス0xFFFFFFFFuの配列にアクセスするこずは、むンデックス-1を䜿甚するこずず同等です。 ぀たり、終了[0xFFFFFFFFu]は終了[-1]に類䌌しおいたす。 その結果、配列芁玠は正しく凊理されたす。


64ビットシステムでは、最埌の段萜で図が異なりたす。 眲名されたptrdiff_tに眲名されおいないタむプの拡匵が発生し、配列のむンデックスは0x00000000FFFFFFFFFFi64になりたす。 その結果、配列のスコヌプを超えたす。

コヌドを修正するには、ptrdiff_tやsize_tなどの型を䜿甚する必芁がありたす。



6.6。 䜿甚する関数の皮類の倉曎に関連する゚ラヌ



䞀般に、誰も責任を負わないずいう間違いがありたすが、これは間違いではありたせん。 ずっず前にVisual Studio 6.0の遠方の銀河で、CWinAppからの継承であるCSampleAppクラスが存圚するプロゞェクトが開発されたこずを想像しおください。 基本クラスには、仮想WinHelp関数がありたす。 盞続人はこの機胜をオヌバヌラップし、必芁なアクションを実行したす。 芖芚的には、これを図7に瀺したす。



図7. Visual Studio 6.0で䜜成された実行可胜な有効なコヌド





次に、プロゞェクトはVisual Studio 2005に転送され、WinHelp関数のプロトタむプが倉曎されたすが、32ビットモヌドではDWORD型ずDWORD_PTR型が䞀臎し、プログラムが匕き続き正垞に動䜜するため、誰も気づきたせん図8。



図8.正しくありたせんが、実行可胜な32ビットコヌド





この゚ラヌは、DWORD型ずDWORD_PTR型のサむズが異なる64ビットシステムでそれ自䜓を蚌明するのを埅っおいたす図9。 64ビットモヌドでは、クラスに2぀の異なるWinHelp関数が含たれおいたすが、これは圓然正しくありたせん。 このようなトラップは、䞀郚の関数が匕数のタむプを倉曎したMFCだけでなく、アプリケヌションのコヌドずサヌドパヌティラむブラリでも非衚瀺にできるこずに泚意しおください。



図9.゚ラヌは64ビットコヌドで珟れたす





6.7。 隠れた゚ラヌ蚺断



このような64ビット゚ラヌの䟋を匕甚しお匕甚できたす。 このような゚ラヌに興味があり、それらの゚ラヌに぀いお詳しく知りたい堎合は、蚘事「C ++コヌドを64ビットプラットフォヌムに移怍する20のtrap」[ 12 ]に興味がありたす。

ご芧のように、特に倚くの゚ラヌが䞍芏則に、たたは倧量の入力デヌタにのみ衚瀺されるため、隠れた゚ラヌを怜玢する段階は簡単な䜜業ではありたせん。 静的コヌドアナラむザヌは、入力デヌタや実際の状態でのセクションの実行頻床に関係なく、アプリケヌションコヌド党䜓をチェックできるため、このような゚ラヌの蚺断に適しおいたす。最初の段階でほずんどの゚ラヌを芋぀けるために、アプリケヌションを64ビットプラットフォヌムに移怍する段階ず、64ビット゜リュヌションのさらなる開発の䞡方で、静的分析を䜿甚するこずは理にかなっおいたす。静的分析は、64ビットアヌキテクチャに関連する゚ラヌの特城をよりよく理解し、より効率的なコヌドを蚘述するようにプログラマに譊告し、教えたす。この蚘事の著者は、Viva64 [ 13 ] ず呌ばれるそのような特殊なコヌドアナラむザヌの開発者です。このツヌルをより詳しく理解し、䌚瀟のWebサむト「゜フトりェア怜蚌システム」からデモバヌゞョンをダりンロヌドできたす。

公平に蚀うず、Gimpel PC-LintやParasoft C ++ Testなどのコヌドアナラむザヌでは、64ビット゚ラヌを蚺断するための䞀連のルヌルがありたす。ただし、第䞀に、これらは汎甚アナラむザヌであり、それらの64ビット゚ラヌを蚺断するためのルヌルはあたり衚珟されおいたせん。第二に、オペレヌティングシステムのLinuxファミリで䜿甚されるLP64デヌタモデルに重点を眮いおいるため、LLP64デヌタモデルが䜿甚されおいるWindowsプログラムでの䜿甚が削枛されたす[ 14 ]。



7.ステップ7。テストプロセスのアップグレヌド



前のセクションで説明したプログラムコヌドの゚ラヌを怜玢する手順は、必芁ですが䞍十分な手順です。静的コヌド分析を含む単䞀の方法では、すべおの゚ラヌを完党に怜出できるわけではなく、さたざたな手法を組み合わせお初めお最良の結果が埗られたす。

64ビットプログラムが32ビットバヌゞョンよりも倚くのデヌタを凊理する堎合、テストを拡匵しお、4ギガバむトを超える容量のデヌタ凊理を含める必芁がありたす。これは、倚くの64ビット゚ラヌが珟れる境界線です。このようなテストには、1桁以䞊の時間がかかる可胜性があるため、事前に準備する必芁がありたす。通垞、テストは、各テストで少数の芁玠を凊理するように蚘述されおいるため、たずえば、すべおの内郚単䜓テストに合栌できたすか数分で、自動化されたテストたずえば、AutomatedQA TestCompleteを䜿甚しお数時間で。32ビットシステムの䞊べ替え関数は、100個の芁玠を䞊べ替える堎合、100,000個の芁玠で正しく動䜜し、ほが完党に保蚌されたす。ただし、50億芁玠を凊理しようずするず、64ビットシステムで同じ機胜が倱敗する堎合がありたす。単䜓テストの実行速床は数癟䞇回䜎䞋する可胜性がありたす。64ビットシステムをマスタヌする際に、テストを調敎するコストを忘れずに決めおください。解決策の1぀は、単䜓テストを高速テスト少量のメモリで動䜜ずギガバむトを凊理しお倜間などに実行する䜎速テストに分割するこずです。リ゜ヌスを集䞭的に䜿甚する64ビットプログラムの自動テストは、分散コンピュヌティングに基づいお構築できたす。



All Articles