intが64ビットの場合に壊れてしまうコードイディオムが1つあり、それは合理的と言えるほど頻繁に見られます。
- 次の場合をテストして、値が負であるかどうかを確認します。
((val & 0x80000000) != 0)
これは通常、エラーコードのチェックで見られます。多くのエラーコード標準(WindowのようなHRESULT
)は、エラーを表すためにビット31を使用します。また、コードは、ビット31をテストするか、エラーが負の数であるかどうかをチェックすることによって、そのエラーをチェックする場合があります。
HRESULTをテストするためのMicrosoftのマクロは両方の方法を使用します。そして、SDKマクロを使用せずに同様のことを行うコードがたくさんあると確信しています。MSがILP64に移行した場合、これは、LLP64モデル(またはLP64モデル)で完全に回避される移植の頭痛の種を引き起こした1つの領域になります。
注:「ILP64」などの用語に慣れていない場合は、回答の最後にあるミニ用語集を参照してください。
これらのintのサイズが32ビットであると仮定すると、エラーコードを保持するためにplain-old-intを使用するコード(必ずしもWindows指向である必要はありません)がたくさんあると確信しています。そして、両方の種類のチェック(< 0
およびビット31が設定されている)も使用し、ILP64プラットフォームに移動すると壊れてしまう、そのエラーステータススキームを備えたコードがたくさんあるに違いありません。これらのチェックは、符号拡張が行われるようにエラーコードが注意深く構築されていれば、どちらの方法でも正しく機能し続けることができますが、繰り返しになりますが、私が見たそのようなシステムの多くは、ビットフィールドの束を組み合わせてエラー値を構築します。
とにかく、これは決して解決できない問題ではないと思いますが、ILP64プラットフォームに移行すると、多くのコードを修正する必要がある、かなり一般的なコーディング手法だと思います。
また、これがMicrosoftがLLP64モデルを選択した最大の理由の1つではないと思うことにも注意してください(MSDN以降で説明されているように、決定は主に32ビットプロセスと64ビットプロセス間のバイナリデータの互換性に基づいていると思います。 Raymond Chenのブログ)。
64ビットプラットフォームプログラミングモデル用語のミニ用語集:
- ILP64:、、
int
ポインタlong
は64ビットです
- LP64:
long
ポインタは64ビット、int
32ビットです(多くの(ほとんどの?)Unixプラットフォームで使用されています)
- LLP64:
long long
およびポインターは64ビットでint
あり、long
32ビットのままです(Win64で使用)
64ビットプログラミングモデルの詳細については、「64ビットプログラミングモデル:なぜLP64なのか」を参照してください。