size_tとstd :: size_tの違い


139

違いは何ですかsize_tstd::size_t、彼らが使用しなければならないとき、宣言し、他の差別化機能している場所の面では?


C ++仕様がstd :: size_tをCのsize_t型にリンクしているかどうかを知りたいです。
Doug T.

同様の質問を参照してください:リンク
Mankarse

回答:


88

C size_tとC ++ std::size_tはどちらも同じです。

Cにおいては、で定義されています<stddef.h>その中で定義され、C ++で<cstddef>、その内容(以下の引用を参照されたい)Cヘッダと同じです。そのように定義された符号なし整数型結果はsizeofオペレータ。

C Standardは§17.7/ 2で、

あるsize_tの符号なし整数型結果はsizeofオペレータ

そしてC ++標準はcstddef§18.1/ 3で(ヘッダーについて)言っています、

内容は標準Cライブラリのヘッダーと同じですが、次の点が異なります

ええ、どちらも同じです。唯一の違いは、C ++ size_tstd名前空間で定義することです。

また、上記の行には「次の変更を伴う」 とあり、を参照していないことにも注意してくださいsize_t。これは、同じヘッダーで定義されている言語(Cには存在しない)へのC ++による(主に)新しい追加を指します。


ウィキペディアには、size_tの範囲とストレージサイズに関する非常に優れた情報があります。

size_tの範囲とストレージサイズ

size_t の実際のタイプは プラットフォームに依存します。一般的な間違いは 、size_tのは、プログラミングエラーにつながることができ、unsigned int型と同じであると仮定することである[3] [4]例えば、64ビットアーキテクチャに32から移動するとき。

1999 ISO C標準(C99)によれば、size_tは少なくとも16ビットの符号なし整数型です。

残りはウィキペディアのこのページから読むことができます。


それは別のQをもたらします。STLがすでにCを介してsize_tをインポートしている場合(cstddef)、なぜ独自の別のバージョンがあるのですか?
Alok Save

43
@Alsは:厳密に言えば、言うことは、エラーであるsize_tなしにusing namespace std;using std::size_t;。ただし、ほとんどのコンパイラーはこれを許可し、標準では特に許可しています(§D.5/ 3)。
Potatoswatter

9
@Potatoswatter:確かに、それはエラーになることも、標準で明確に許可されることもありませんか?それが標準にある場合、それはエラーではありません!
ベンハイマーズ2013

8
@BenHymers標準は、標準ヘッダーが宣言するものを指定し、予約されていない他の名前を宣言することは許可されていません。ヘッダー<cstddef>はを宣言する場合としない::size_t場合があります。そのため、宣言されていること<stddef.h>が保証されているCライブラリからのヘッダーまたは別のヘッダーを明示的にインクルードする場合を除いて、ヘッダーが存在する、または存在しないとは限りません。
Potatoswatter 2013

4
@Potatoswatter:ああ、私はあなたが今何を言っているのか分かります!私は、1つの文に含まれる「許可」が多すぎて混乱したに違いありません。まだ最初のコメントは強すぎると思います。先ほど言ったように、::size_tはに存在する<stddef.h>ため、常にで修飾する必要はありませんstd::
ベンハイマーズ2013

16

C ++ 03「17.4.3.1.4タイプ」から:

標準Cライブラリ(脚注169)の各タイプTについて、タイプ:: Tおよびstd :: Tは実装用に予約されており、定義されている場合、:: Tはstd :: Tと同一でなければなりません。

そして脚注169:

これらのタイプは、clock_t、div_t、FILE、fpos_t、lconv、ldiv_t、mbstate_t、ptrdiff_t、sig_atomic_t、size_t、time_t、tm、va_list、wctrans_t、wctype_t、およびwint_tです。


では、移植可能なコードは、std::T定義されているバリアントに依存すべきではないのですか?
マンカルス

5
@Mankarse:対応するヘッダーのCバージョンのみを含める場合は、それらが定義されていることに依存しないでください。場合は#include <stddef.h>、その後std::size_tたり、使用できない場合があります。あなたがもし#include <cstddef>、次にstd::size_t利用可能ですが、size_tではないかもしれません。
Dennis Zickefoose

4
@Mankarse:反対です。ヘッダーのC ++バージョンではそれらを定義する必要がstd::あり、段落では、それらをトップレベルのネームスペースで定義することもでき、定義する場合はそれらをトップレベルでも同じように定義する必要があると述べていstd::ます。ほとんどのコンパイラはCヘッダーをインクルードし、名前をstd::にインポートするだけなので、シンボルは両方で定義されます。
Jan Hudec

4
個人的には、<cxxxxx>ヘッダーやstd::Cの海岸から来る識別子のバリアントを気にすることはありません。私<xxxxx.h>は標準のCヘッダーにこだわっています-それは問題ではありませんでした。それで、私は使用<stddef.h>size_t、決して考え直しませんstd::size_t。実際、が存在する(または存在する可能性がある)ことを頭に浮かぶことはありませんstd::size_t
Michael Burr

12

std :: size_tは、実際にはstddef.hsize_tです。

cstddefは以下を提供します。

#include <stddef.h>
namespace std 
{
  using ::ptrdiff_t;
  using ::size_t;
}

...以前の定義をstd名前空間に効果的に取り込みます。


Nawazが指摘するように、それは実際には逆です。あなたは含めることはできません<cstddef>し、取得できると期待し::size_tていますが、含まれている場合<stddef.h>、あなたが取得しますstd::size_t
MSalters 2011

4
@MSalters、フォローしていません。含める<stddef.h>だけであなたを取得します::size_t
ハイファイア

2
それはあなたの実装のバグです。
MSalters、2011年

4
@MSalters、私は完全には従いません。それは逆にしてはいけませんか?<cstddef>はC ++からのものであるため、std :: *?一方、stddef.hのようなCヘッダーでは、Cの型、つまり:: size_tのみを期待します。
Ela782 2014年

11
@ MSalters、C ++ 11以降は正確ではありません。含める<cstddef>と、確実に取得され、取得されるstd::size_t可能性もあります::size_t(ただし、それは保証されません)。含める<stddef.h>と、確実に取得され、取得される::size_t可能性もありますstd::size_t(ただし、それは保証されません)。これはC ++ 03では異なりましたが、事実上実装できず、不具合として修正されました。
Jonathan Wakely
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.