このタイプで定義された変数が表示されますが、どこから来たのか、またその目的は何なのかわかりません。なぜintまたはunsigned intを使用しないのですか? (他の「類似」タイプはどうですか?Void_tなど)。
From Wikipedia
stdlib.h
およびstddef.h
ヘッダーファイルは、サイズを表すために使用されるsize_t
1 というデータ型を定義しますオブジェクト。サイズを取るライブラリ関数は、それらがsize_t
型であると想定し、sizeof演算子はsize_t
と評価されます。
size_t
の実際のタイプはプラットフォームに依存します。よくある間違いは、size_t
がunsigned intと同じであると仮定することです。これはプログラミングエラーにつながる可能性があります。 2 特に64ビットアーキテクチャとしてより一般的になります。
From C99 7.17.1/2
次のタイプとマクロは、標準ヘッダー
stddef.h
で定義されています<スニップ>
size_t
これは、sizeof演算子の結果の符号なし整数型です
size_t
は、sizeof演算子の結果の符号なし整数型です(ISO C99セクション7.17。)
sizeof
演算子は、そのオペランドのサイズ(バイト単位)を生成します。これは、式または括弧付きの型名です。サイズは、オペランドのタイプから決定されます。結果は整数です。結果の値は実装定義であり、その型(符号なし整数型)はsize_t
(ISO C99セクション6.5.3.4。)です。
en.cppreference.comのsize_tの説明size_t
によると、次のヘッダーで定義されます。
std::size_t
...
Defined in header <cstddef>
Defined in header <cstdio>
Defined in header <cstring>
Defined in header <ctime>
Defined in header <cwchar>
実質的にsize_t
は、アドレス可能なバイト数を表します。過去10〜15年間のほとんどの最新のアーキテクチャでは、32ビットであり、これも符号なし整数のサイズでした。ただし、uint
は32ビットのままである可能性が高い一方で、64ビットアドレスに移行しています(c ++標準ではサイズが保証されていません)。メモリサイズに依存するコードをアーキテクチャ間で移植可能にするには、size_t
を使用する必要があります。たとえば、配列サイズなどでは常にsize_t
を使用する必要があります。標準コンテナを見ると、::size()
は常にsize_t
を返します。
また、Visual Studioには、「64ビットの移植性の問題を検出する」と呼ばれるこれらのタイプのエラーをチェックできるコンパイルオプションがあります。
この方法では、特定のタイプがサイズ専用であるため、サイズが常に把握されます。非常に独自の質問は、それが問題になる可能性があることを示しています:それはint
またはunsigned int
ですか?また、大きさ(short
、int
、long
など)は何ですか?
特定のタイプが割り当てられているため、長さや署名の有無を心配する必要はありません。
実際の定義は C++ Reference Library にあります。
タイプ:
size_t
(符号なし整数タイプ)ヘッダー:
<cstring>
size_t
は、言語演算子sizeof
によって返される整数データ型に対応し、<cstring>
ヘッダーファイル(とりわけ)で符号なし整数型として定義されます。
<cstring>
では、関数num
、memchr
、memcmp
、memcpy
、memmove
、memset
、strncat
、strncmp
、およびstrncpy
のパラメーターstrxfrm
のタイプとして使用されます。関数が影響しなければならないバイト数または文字数。また、
strcspn
、strlen
、strspn
、およびstrxfrm
の戻り型として使用され、サイズと長さを返します。
size_tは、標準ライブラリのヘッダーで定義する必要があります。私の経験では、通常は単にunsigned intのtypedefです。しかし、ポイントはそうである必要がないということです。 size_tのような型を使用すると、標準ライブラリベンダーは、プラットフォームに適切な場合、基になるデータ型を自由に変更できます。 size_tが常に(キャストなどを介して)unsigned intであると仮定した場合、ベンダーがsize_tを変更すると、将来問題が発生する可能性があります。 64ビット型。この理由から、これまたは他のライブラリタイプについて何かを想定することは危険です。
size_t
定義がいくつかのインクルードで「偶然」読み込まれなかったが、いくつかのコンテキストでまだ必要な場合(たとえば、std::vector<double>
にアクセスするため)、thatコンテキストを使用して正しいタイプを抽出します。たとえば、typedef std::vector<double>::size_type size_t
。
(スコープを制限する必要がある場合は、namespace {...}
で囲みます。)
Google検索の結果を除いてvoid_t
に詳しくない( AT&T ResearchのKiem-Phong Voによるvmalloc
ライブラリで使用されている -確かだ他のライブラリでも使用されています)。
さまざまなxxx_t typedefは、特定の明確な実装から型を抽象化するために使用されます。これは、特定のものに使用される具体的な型がプラットフォームごとに異なる場合があるためです。例えば:
Void_t
は、vmalloc
キーワードが存在しない可能性のあるANSI/ISO Cより前のシステムで動作するように作成されているため、void
ライブラリルーチンによって返されるポインターのタイプを抽象化します。少なくともそれは私が推測するものです。wchar_t
は、一部のシステムでは16ビット型になり、他のシステムでは32ビット型になるため、ワイド文字に使用される型を抽象化します。したがって、たとえばwchar_t
の代わりにunsigned short
タイプを使用するワイド文字処理コードを記述すると、そのコードはおそらくさまざまなプラットフォームにより移植可能になります。
「なぜintまたはunsigned intを使用しないのですか?」というのは、単に意味的に意味がないからです。 typedef
dをint
として、その後long
にアップグレードできるという実用的な理由があります。もちろん、誰もコードを変更する必要はありませんが、基本的には型には意味があるはずです。大幅に単純化するために、size_t
型の変数は、time_t
が時間値の格納に適しているのと同様に、物のサイズを格納するのに適しています。これらが実際にどのように実装されるかは、実装の仕事です。すべてのint
を呼び出すだけの場合と比較して、このような意味のある型名を使用すると、豊富な型のセットが行うように、プログラムの意味と意図を明確にするのに役立ちます。