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