私は現在、Cで32ビットアプリケーションを64ビットアプリケーションに変換する作業を行っています。このアプリケーションは現在、x86アーキテクチャ(Windows、osx、Unix、Linux)で動作しています。そのため、コーディングを開始する前に、アプリケーションを変換するときに何を考慮する必要があるかを知りたいと思いました。
LONG
はlong
ではないことに完全に注意してください。(int)&x
_キャストと入力を_intptr_t
_に置き換え、_(unsigned int)&x
_を_uintptr_t
_に置き換えますchar*
_にキャストしてポインター演算を行うことに依存するものはすべて監査します。4 = sizeof(void*)
を想定した場合、正規表現で\ <4 \>を検索します#ifdef RUN64
_または同様のものを使用しないようにしてください。 128ビットプラットフォームが流行した場合は、後悔するでしょう。[〜#〜] edit [〜#〜]コメントで提案されているように_uintptr_t
_メモを追加しました。
まだ言及されていない潜在的な問題の1つは、アプリがディスクからバイナリデータを読み書きする場合(たとえば、fread
を使用して構造体の配列を読み取る場合)、非常に注意深くチェックする必要があり、おそらく2つになることです。リーダー:1つはレガシーファイル用、もう1つは64ビットファイル用です。または、uint32_t
ヘッダーファイルから<stdint.h>
などのタイプを慎重に使用する場合は、構造体をビットごとに互換性があるように再定義できます。いずれにせよ、バイナリI/Oは注意が必要です。
これは、実際にはアプリケーションとそのコーディング方法によって異なります。一部のコードは64ビットコンパイラで再コンパイルでき、正常に機能しますが、通常、これはコードが移植性を考慮して設計されている場合にのみ発生します。
コードにネイティブタイプとポインターのサイズに関する多くの仮定がある場合、ビットパッキングハックが多い場合、またはバイト指定プロトコルを使用して外部プロセスと通信するが、ネイティブタイプのサイズに関するいくつかの仮定を使用している場合クリーンなコンパイルを行うには、いくらか、または多くの作業が必要になる場合があります。
ほとんどすべてのキャストとコンパイラの警告は、チェックアウトが必要な危険信号です。コードが最初から「警告クリーン」ではなかった場合、それは多くの作業が必要になる可能性があることの兆候でもあります。
値に正しいタイプを使用した場合-例: size_t
、ptrdiff_t
、uintptr_t
、必要に応じてstdint.h
からの固定サイズのint型-値のサイズをハードコーディングしなかった場合、コードはそのままで機能するはずです。
64ビットに切り替えるときに直面する主な問題は、ポインターのサイズが異なることです(32ビットではなく64ビット)。プラットフォームによっては、整数のサイズとlongのサイズも異なる場合があります。
なぜこれが問題なのですか?コードでsizeof(int)== sizeof(void *)と想定されていない限り、そうではありません。これは厄介なポインタのバグにつながる可能性があります。
さて、基本的に、変更の数はかなり少ないですが、アプリケーションが最初からある程度移植可能であるように注意深く書かれていない場合、それは依然として主要なタスクになります。
主な違いは、ポインタの幅が64ビットであるということです。しかし他のほとんどのデータ型は変更されていません。 intはまだ32ビットであり、longもおそらく32ビットです。したがって、コードがintとpointersの間でキャストする場合、それは壊れます。同様に、メンバーへの特定のオフセットに依存する構造体などは、他のメンバーが大きくなる可能性があるために破損する可能性があるため、オフセットを変更します。
もちろん、コードはそもそもこれらのトリックに依存するべきではないので、理想的な世界では、これはまったく問題にはならず、単に再コンパイルするだけですべてが機能します。しかし、あなたはおそらく理想的な世界に住んでいないでしょう...;)
Cでの32ビットプログラミングと64ビットプログラミングの2つの大きな違いは、sizeof(void *)とsizeof(long)です。発生する主な問題は、ほとんどのUnixシステムが64ビットの長さを定義するI32LP64標準を使用し、Win64が32ビットの長さを定義するIL32LLP64標準を使用することです。クロスプラットフォームコンパイルをサポートする必要がある場合は、32ビットおよび64ビット整数のアーキテクチャベースのtypedefのセットを使用して、すべてのコードが一貫して動作するようにすることができます。これは、C99標準の一部としてstdint.hの一部として提供されます。 C99コンパイラを使用していない場合は、独自の同等のコンパイラをロールする必要がある場合があります
他の場所で述べたように、変換の主な懸念事項は、sizeof(int)== sizeof(long)== sizeof(void *)を想定するコード、ディスクに書き込まれたデータをサポートするコード、およびクロスプラットフォームIPCのコードです。
この背後にある歴史の良いレビューについては、これを見てください 記事 ACMキューから。
すでにたくさんの良い答えがあります。
Gimpel Lint の使用を検討してください。問題のある構成のタイプを正確に指摘できます。あなたの経験が私のようなものであれば、32/64ビットポートとは関係のないシステムの多くのバグも表示されます。