1. ホーム
  2. c

[解決済み】size_tとuintptr_tの比較

2022-04-05 17:23:56

質問

C言語規格は次のことを保証しています。 size_t は、任意の配列インデックスを保持することができる型です。これはつまり、論理的には size_t は、どんなポインタ型でも保持できるはずです。Googleで見つけたいくつかのサイトでは、これは合法であり、かつ/または、常に動作するはずだと書いてありました。

void *v = malloc(10);
size_t s = (size_t) v;

そこで、C99では、標準に intptr_tuintptr_t これは、ポインタを保持できることが保証された符号付きおよび符号なしタイプです。

uintptr_t p = (size_t) v;

では size_tuintptr_t ? どちらも符号なし、どちらもどんなポインタ型でも保持できるはずなので、機能的には同じように見えます。を使うべき本当に説得力のある理由があるのでしょうか? uintptr_t (いっそのこと void * ではなく size_t 明確であること以外には?不透明な構造で、フィールドが内部関数によってのみ処理される場合、これを行わない理由がありますか?

同じ意味で ptrdiff_t はポインタの差分を保持することができる符号付き型であり、したがってほとんどのポインタを保持することが可能であったので、どのように intptr_t ?

これらのタイプは、基本的に同じ機能の些細な異なるバージョンを提供していないのでしょうか?もしそうでないなら、なぜですか?このうちの一つでできなくて、別のものでできることは何でしょうか?もしそうなら、なぜC99は本質的に余分な2つの型を言語に追加したのでしょうか?

関数ポインタは今回の問題には当てはまらないので無視しても構いませんが、quot;correct"の答えの中心になるのではないかと思うので、遠慮なく言及してください。

解決方法は?

<ブロッククオート

size_t は、任意の配列インデックスを保持することができる型です。ということです。 論理的には、size_t は 任意のポインタ型を保持する

必ずしもそうではありません。 例えば、セグメント化された16ビット・アーキテクチャの時代を思い出してください:配列は1つのセグメントに制限されているかもしれません(だから16ビット size_t しかし、複数のセグメントを持つことができます。 intptr_t タイプは、セグメントとその中のオフセットを選択するために必要です。) しかし、標準規格は、2009年に一般的とされるものよりも幅広い種類に対応しなければならないのです。)