2017-10-26 3 views
0

WindowsではBaseTsd.hには、POINTER_SIGNEDPOINTER_UNSIGNEDの2つのマクロがあり、それぞれ__sptr__uptrに解決されています。 According to Microsoft's documentationこれらは、コンパイラが32ビットポインタを64ビットポインタに変換する方法をと指定するディレクティブです。POINTER_SIGNEDまたはPOINTER_UNSIGNEDのケースを使用しますか?

__sptrこれは、ポインタを符号付きとして扱い、それを64ビットに変換するため、負のポインタが負として拡張されますが、これは誤って最上位ビットを符号ビットとして扱うことになりますこれは場合によっては望ましくないかもしれない。

したがって__uptrが作成されました。この場合、ポインタは符号なしとして処理され、符号なしとして拡張されます。今、私はどのような状況がこのような構造を必要とするのかを理解することができず、どれが最も適しているのかを理解するのに困っています。

intまたはunsigned intから64ビットプラットフォームの場合と同じようにポインタを逆参照する代わりに__ptr32を使用する利点は何ですか?どちらも一般的に未定義の振る舞いを呼び出すでしょう。 __sptr__uptrの間でどのように選択するのですか?

+0

現代のC++ 11コンパイラでは、これらのWin32移植性のタイプを実際に使用するべきではありません。 [ptrdiff_t](http://en.cppreference.com/w/cpp/types/ptrdiff_t)と[size_t](http://en.cppreference.com/w/cpp/types/size_t)を使用するだけで、 –

答えて

1

32ビットポインタは、従来のコードの移植補助としてのみ使用されます。 多分、Wow64レイヤーのインプリメンテーションの中でMicrosoftによって使用されているかもしれませんが、それは唯一の推測です。

大きなアドレス認識フラグを無効にすると、Visual Studioでwith corresponding Linker optionを実行すると、64ビットアプリケーションで32ビットポインタを使用できます。次に、すべての割り当てが2 GBに制限されます。これは64ビットアプリケーションの目的を捨てるが、古いクラップスをx64に移植するのに役立つかもしれない。

とにかく32ビットポインタをポインタとして持つのは、値がポインタを含み、任意の値ではないことがわかっているので、32ビットintよりもきれいです。

署名/未署名について。私はわかりませんが、私は次の推測を持っています:

通常、32ビットのアプリケーションと32ビットOSでは、アドレス可能な2 GBはプログラムの仮想アドレス空間です。上位アドレス可能な2 GBはカーネル空間です。 64ビットOSカーネル空間では、64ビット空間の中では非常にテラバイトです。したがって、符号付きポインタの変換は、アプリケーションのスペースをアプリケーションのスペースに、禁止されたスペースを禁止されたスペースに変換します。

32ビットアプリケーション用の大規模アドレス対応と32ビットOS用の/ 3GBスイッチを有効にした場合、アプリケーションの領域(最大3 GB)が確保され、すべてのアプリケーションのポインタ、あなたは符号なしのタイプを好むでしょう。

関連する問題