web-dev-qa-db-ja.com

size_tの定義はどこにありますか?

このタイプで定義された変数が表示されますが、どこから来たのか、またその目的は何なのかわかりません。なぜintまたはunsigned intを使用しないのですか? (他の「類似」タイプはどうですか?Void_tなど)。

112
Eliseo Ocampos

From Wikipedia

stdlib.hおよびstddef.hヘッダーファイルは、サイズを表すために使用されるsize_t1 というデータ型を定義しますオブジェクト。サイズを取るライブラリ関数は、それらがsize_t型であると想定し、sizeof演算子はsize_tと評価されます。

size_tの実際のタイプはプラットフォームに依存します。よくある間違いは、size_tがunsigned intと同じであると仮定することです。これはプログラミングエラーにつながる可能性があります。 2 特に64ビットアーキテクチャとしてより一般的になります。

From C99 7.17.1/2

次のタイプとマクロは、標準ヘッダーstddef.hで定義されています

<スニップ>

size_t

これは、sizeof演算子の結果の符号なし整数型です

111

size_tは、sizeof演算子の結果の符号なし整数型です(ISO C99セクション7.17。)

sizeof演算子は、そのオペランドのサイズ(バイト単位)を生成します。これは、式または括弧付きの型名です。サイズは、オペランドのタイプから決定されます。結果は整数です。結果の値は実装定義であり、その型(符号なし整数型)はsize_t(ISO C99セクション6.5.3.4。)です。

25
fpmurphy

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>
24
stefanB

実質的にsize_tは、アドレス可能なバイト数を表します。過去10〜15年間のほとんどの最新のアーキテクチャでは、32ビットであり、これも符号なし整数のサイズでした。ただし、uintは32ビットのままである可​​能性が高い一方で、64ビットアドレスに移行しています(c ++標準ではサイズが保証されていません)。メモリサイズに依存するコードをアーキテクチャ間で移植可能にするには、size_tを使用する必要があります。たとえば、配列サイズなどでは常にsize_tを使用する必要があります。標準コンテナを見ると、::size()は常にsize_tを返します。

また、Visual Studioには、「64ビットの移植性の問題を検出する」と呼ばれるこれらのタイプのエラーをチェックできるコンパイルオプションがあります。

4
Matt Price

この方法では、特定のタイプがサイズ専用であるため、サイズが常に把握されます。非常に独自の質問は、それが問題になる可能性があることを示しています:それはintまたはunsigned intですか?また、大きさ(shortintlongなど)は何ですか?

特定のタイプが割り当てられているため、長さや署名の有無を心配する必要はありません。

実際の定義は C++ Reference Library にあります。

タイプ:size_t(符号なし整数タイプ)

ヘッダー:<cstring>

size_tは、言語演算子sizeofによって返される整数データ型に対応し、<cstring>ヘッダーファイル(とりわけ)で符号なし整数型として定義されます。

<cstring>では、関数nummemchrmemcmpmemcpymemmovememsetstrncatstrncmp、およびstrncpyのパラメーターstrxfrmのタイプとして使用されます。関数が影響しなければならないバイト数または文字数。

また、strcspnstrlenstrspn、およびstrxfrmの戻り型として使用され、サイズと長さを返します。

2
lavinio

size_tは、標準ライブラリのヘッダーで定義する必要があります。私の経験では、通常は単にunsigned intのtypedefです。しかし、ポイントはそうである必要がないということです。 size_tのような型を使用すると、標準ライブラリベンダーは、プラットフォームに適切な場合、基になるデータ型を自由に変更できます。 size_tが常に(キャストなどを介して)unsigned intであると仮定した場合、ベンダーがsize_tを変更すると、将来問題が発生する可能性があります。 64ビット型。この理由から、これまたは他のライブラリタイプについて何かを想定することは危険です。

2
Ryan

size_t定義がいくつかのインクルードで「偶然」読み込まれなかったが、いくつかのコンテキストでまだ必要な場合(たとえば、std::vector<double>にアクセスするため)、thatコンテキストを使用して正しいタイプを抽出します。たとえば、typedef std::vector<double>::size_type size_t

(スコープを制限する必要がある場合は、namespace {...}で囲みます。)

1
alfC

Google検索の結果を除いてvoid_tに詳しくない( AT&T ResearchのKiem-Phong Voによるvmallocライブラリで使用されている -確かだ他のライブラリでも使用されています)。

さまざまなxxx_t typedefは、特定の明確な実装から型を抽象化するために使用されます。これは、特定のものに使用される具体的な型がプラットフォームごとに異なる場合があるためです。例えば:

  • size_tは、オブジェクトのサイズを保持するために使用される型を抽象化します。これは、一部のシステムでは32ビット値になり、他のシステムでは16ビットまたは64ビットになるためです。
  • Void_tは、vmallocキーワードが存在しない可能性のあるANSI/ISO Cより前のシステムで動作するように作成されているため、voidライブラリルーチンによって返されるポインターのタイプを抽象化します。少なくともそれは私が推測するものです。
  • wchar_tは、一部のシステムでは16ビット型になり、他のシステムでは32ビット型になるため、ワイド文字に使用される型を抽象化します。

したがって、たとえばwchar_tの代わりにunsigned shortタイプを使用するワイド文字処理コードを記述すると、そのコードはおそらくさまざまなプラットフォームにより移植可能になります。

1
Michael Burr

「なぜintまたはunsigned intを使用しないのですか?」というのは、単に意味的に意味がないからです。 typedefdをintとして、その後longにアップグレードできるという実用的な理由があります。もちろん、誰もコードを変更する必要はありませんが、基本的には型には意味があるはずです。大幅に単純化するために、size_t型の変数は、time_tが時間値の格納に適しているのと同様に、物のサイズを格納するのに適しています。これらが実際にどのように実装されるかは、実装の仕事です。すべてのintを呼び出すだけの場合と比較して、このような意味のある型名を使用すると、豊富な型のセットが行うように、プログラムの意味と意図を明確にするのに役立ちます。

1
Paul Griffiths