size_t
コードをコンパイルしたマシンのワードサイズはありますか?
g ++で解析すると、私のコンパイラはをと見なしsize_t
ますlong unsigned int
。コンパイラは内部でサイズを選択しますかsize_t
、それとも実際には、コンパイラが呼び出される前に、size_t
プリプロセッサマクロ内でワードサイズにtypdefされますか?stddef.h
それとも私は軌道から外れていますか?
C ++標準では、[support.types](18.2)/ 6:「この型size_t
は、任意のオブジェクトのバイト単位のサイズを含むのに十分な大きさの、実装定義の符号なし整数型です。」
これは、「ワードサイズ」と同じである場合とそうでない場合があります。
いいえ; size_t
コードを実行するマシン(クロスコンパイルの場合)またはコードをコンパイルしたマシン(コードが同じタイプのマシンで実行される通常の場合)の「ワードサイズ」が意味するものとは限りません。コードをコンパイルしました)。これは、実装が割り当てることができる最大のオブジェクトのサイズ(バイト単位)を保持するのに十分な大きさの符号なし整数型です。
sizeof
とのいくつかの歴史size_t
正確にいつ導入されたかはわかりませんsize_t
が、1979年から1989年の間でした。K&Rの第1版1978年のCプログラミング言語には、の言及がありませんsize_t
。第7版Unixプログラマーマニュアルにはまったく言及されておらずsize_t
、1979年にさかのぼります。1984年のKernighanとPikeによる本「UNIXプログラミング環境」size_t
は、索引に言及されていません(malloc()
またはfree()
、少し驚いたことに) 、しかしそれは単なる指標であり、決定的なものではありません。C89規格には確かにがありsize_t
ます。
sizeof()
C99 Rationaleは、およびに関するいくつかの情報を文書化していますsize_t
。
6.5.3.4sizeof演算子
malloc
となどの関数を正しく使用するための基本は、fread
まさにsizeof(char)
1つです。実際には、これは、この単位が36ビット幅であっても、C用語のバイトがストレージの最小単位であることを意味します。すべてのオブジェクトは、これらの最小単位の整数で構成されています。メモリがビットアドレス可能である場合にも適用されます。C89は、K&Rと同様に、sizeof
演算子の結果を符号なし整数型の定数として定義しました。一般的な実装と一般的な使用法では、結果の型がであると想定されることがよくありint
ます。この動作に依存する古いコードは、結果を。以外の型として定義する実装に移植できませんでしたint
。C89委員会は、誤ったコードを保護するために言語を変更することが適切であるとは感じていませんでした。のタイプは、それが何であれ、プログラマーがこのタイプを参照できるようにするのに役立つため、
sizeof
(ライブラリヘッダーで<stddef.h>
)として 公開されます。この要件は、既存の符号なし整数型の同義語になるようにsize_t
暗黙的に制限します。size_t
またsize_t
、符号なし型sizeof
ですが、サイズが大きすぎてを表すことができない場合にモジュラス動作を引き起こす算術演算や変換を含まないため、size_t
宣言可能な最大のオブジェクトが大きすぎてスパンできない可能性があるという概念を打ち砕くことにも注意してください。unsigned long
C89またはC99でもuintmax_t
。これにより、配列で宣言できる要素の最大数も制限されます。これは、要素の任意の配列a
についてN
、
N == sizeof(a)/sizeof(a[0])
したがって
size_t
、配列サイズにも便利なタイプであり、いくつかのライブラリ関数で使用されます。[...]7.17一般的な定義
<stddef.h>
は、ライブラリと組み合わせて広く使用されるいくつかのタイプとマクロの定義を提供するために考案されたヘッダーです:ptrdiff_t
、、、、。これらのマクロの1つを参照するヘッダーを含めると、それも定義されます。これは、各マクロまたは関数が1つのヘッダーにのみ属するという通常のライブラリルールの例外です。size_t
wchar_t
NULL
<stddef.h>
これは、C89委員会によって発明されたことを具体的に述べていることに注意してください。それもC89委員会によって発明されたという言葉は見つかりませんでしsize_t
たが、そうでない場合は、Cのかなり最近の開発の成文化でした。
bmarguliesの 回答へのコメントで、フォンブランドは「それsize_t
は確かにANSI-C-ismである」と述べています。それが元のANSI(ISO)Cの革新であったことは非常に簡単に信じられますが、理論的根拠がそれを述べていないのは少し奇妙です。
必ずしも。C ISO仕様(§17.1 / 2)は次のように定義しsize_t
ています
sizeof
size_tは、演算子の結果の符号なし整数型です。
つまり、size_t
から生成できる式のサイズを保持するのに十分な大きさである必要がありますsizeof
。これはマシンワードサイズである可能性がありますが、劇的に小さい場合(たとえば、コンパイラが配列またはオブジェクトの最大サイズを制限している場合)または劇的に大きい場合(コンパイラが単一のマシンのように非常に大きなオブジェクトを作成できる場合)ワードはそのオブジェクトのサイズを保存できませんでした)。
お役に立てれば!
size_tは、元々、sys / types.h(従来はUnix / Linux)のtypedefでした。たとえば、ファイルの最大サイズ、またはmallocでの最大割り当てに対して「十分な大きさ」であると想定されていました。ただし、時間の経過とともに、標準の委員会がそれを取得したため、多くの異なるヘッダーファイルにコピーされ、複数の定義から独自の#ifdef保護で毎回保護されました。一方、潜在的なファイルサイズが非常に大きい64ビットシステムの出現は、その役割を曇らせました。だから、それはちょっとしたパリンプセストです。
言語標準では、stddef.hに存在すると呼ばれるようになりました。ハードウェアのワードサイズやコンパイラの魔法とは必要な関係はありません。それらの基準がどれほど大きいかについて述べていることに関して、他の回答を参照してください。
このような定義はすべて実装定義です。最適な推測サイズが必要な場合は、sizeof(char *)、またはsizeof(void *)を使用します。これがもたらす最良の方法は、ソフトウェアが使用する見かけのワードサイズです...ハードウェアが実際に持っているものは異なる場合があります(たとえば、32ビットシステムはソフトウェアによって64ビット整数をサポートする場合があります)。
また、C言語を初めて使用する場合は、整数サイズのあらゆる種類の資料についてstdint.hを参照してください。
定義はタイプが正確に何であるかを直接述べておらず、最小サイズも必要としませんが、size_t
間接的にいくつかの良いヒントを与えます。Aは、任意のオブジェクトのサイズをバイト単位で含めることができる必要があります。つまり、可能な最大のオブジェクトのサイズを含めることができる必要があります。size_t
可能な最大のオブジェクトは、使用可能なアドレス空間全体に等しいサイズの配列(または構造体)です。大きなオブジェクトを意味のある方法で参照することはできません。また、スワップスペースが利用できることを除けば、それを小さくする必要がある理由はありません。
したがって、定義の言い回しでは、32ビットアーキテクチャでは少なくとも32ビット、64ビットシステムでは少なくとも64ビットであるsize_t
必要があります。もちろん、実装でより大きなものを選択することは可能ですが、size_t
通常はそうではありません。