C標準でsize_t
は、任意の配列インデックスを保持できる型であることを保証しています。つまり、論理的には、size_t
任意のポインタ型を保持できる必要があります。これは合法であり、常に機能するはずであるとGoogleで見つけたいくつかのサイトで読んだことがあります。
void *v = malloc(10);
size_t s = (size_t) v;
そのため、C99では、標準によりintptr_t
およびuintptr_t
型が導入されました。これらは、ポインタを保持できることが保証されている符号付きおよび符号なしの型です。
uintptr_t p = (size_t) v;
だから、使用しての違いは何であるsize_t
とはuintptr_t
?どちらも符号なしであり、どちらも任意のポインタ型を保持できるはずなので、機能的には同じように見えます。明快さ以外に、aよりもuintptr_t
(またはもっと良いのはa void *
)を使用する本当に説得力のある理由はありますsize_t
か?フィールドが内部関数によってのみ処理される不透明な構造で、これを行わない理由はありますか?
同様に、ptrdiff_t
ポインタの違いを保持できる符号付きの型であり、したがってほとんどのポインタを保持できるので、それはどのように区別されintptr_t
ますか?
これらのタイプはすべて、基本的に同じ機能のわずかに異なるバージョンを提供しているのではないですか?そうでない場合、なぜですか?それらの1つを使用して、他のユーザーを使用してできないことは何ですか?もしそうなら、なぜC99は2つの本質的に不必要な型を言語に追加したのですか?
関数ポインターは現在の問題には当てはまらないため、無視してもかまいませんが、「正しい」答えの中心となるのではないかという疑惑があるので、遠慮なく触れてください。
size_t
し、uintptr_t
しかし、何についてptrdiff_t
とをintptr_t
-これらの両方は、ほぼすべてのプラットフォーム上で同じ値の範囲を保存することはできないでしょうか?特に、ptrdiff_t
既に符号付きポインターサイズの整数型の目的を果たしている場合に、符号付きと符号なしの両方のポインターサイズの整数型がある理由。