web-dev-qa-db-ja.com

size_tは常に符号なしですか?

タイトルとして:size_tは常に符号なし、つまりsize_t xxは常に>= 0

57
peterchen

はい。これは通常次のようなものとして定義されています(32ビットシステム):

typedef unsigned int size_t;

参照:

C++標準セクション18.1ではsize_t<cstddef>これは、C標準では<stddef.h>
C標準セクション4.1.5ではsize_tは、sizeof演算子の結果の符号なし整数型として

48
Mehrdad Afshari

1999 ISO C標準(C99)によると、size_tは少なくとも16ビットの符号なし整数型です(セクション7.17および7.18.3を参照)。

また、標準では、可能であればsize_tの整数変換ランクをlongより大きくしないことを推奨しています。つまり、推奨事項に従えばsize_tからunsigned longへのキャストは問題ありません。

1989年のANSI C標準(ANSI C)では、最小サイズや推奨される変換ランクについては言及されていません。

1998 ISO C++標準(C++ 98)(およびC++ 0xの現在のドラフト)は、C標準を参照しています。セクション18.1の内容:

内容は、標準Cライブラリヘッダー<stddef.h> [...]と同じです

セクション1.2によると、これは1995 ISO C標準(C90)で定義されたライブラリを意味し、1995年からの最初の修正(C95)を含みます。

ISO/IEC 9899:1990の7節およびISO/IEC 9899/AMD.1:1995の7節で説明されているライブラリは、これ以降標準Cライブラリと呼ばれます。

size_tに関する部分は、ANSI Cから継承する必要があります。Frontmatterとセクション番号は別にして、C90とANSI Cの標準は同じです。 stddef.hに関連する変更がないことを確認するために、規範的修正のコピーが必要ですが、私はそれを疑います。最小サイズは、stdint.h、つまりC99で導入されたようです。

C++ 98のセクション1.2からの次の引用も考慮してください。

すべての規格は改訂の対象であり、この国際規格に基づく合意の当事者は、以下に示す規格の最新版を適用する可能性を調査することが推奨されます。

51
Christoph

はい、size_tは符号なしの型であることが保証されています。

14
nos

標準によれば、これは署名されていませんが、古い実装の中にはtypedefに署名された型を使用したものがあることを思い出します。

古いGCCドキュメントから:

Size_tタイプとリリース2.4より前のGCCのバージョンには潜在的な問題があります。 ANSI Cでは、size_tが常に符号なしの型である必要があります。既存のシステムのヘッダーファイルとの互換性のために、GCCはsize_tstddef.hを、システムのsys/types.hが定義するタイプに定義します。 size_tsys/types.hを定義するほとんどのUnixシステムは、それを署名付きタイプとして定義します。ライブラリ内の一部のコードはsize_tが符号なしの型であることに依存しており、署名されている場合は正しく動作しません

それを防ぐことがどれほど重要かはわかりません。私のコードは、それが署名されていないことを前提としています。

5
Michael Burr

Size_tは、C標準と同じ定義に従う必要があり、C++標準のいくつかの場所では、それが符号なしのナチュラであることを意味します(特にアロケーターテンプレート引数の定義)。

C++標準のセクション18.1(ISO/IEC 14882-初版1998-01-01):

表15は、定義済みのタイプとしてリストされています:ptrdiff_tおよびsize_t

3内容は標準Cライブラリヘッダーと同じですが、以下の変更があります。4マクロNULLは、この国際標準(4.10)の実装定義のC++ nullポインター定数です。

マクロoffsetofは、この国際標準の型引数の制限されたセットを受け入れます。タイプは、POD構造体またはPODユニオンでなければなりません(9項)。静的データメンバーまたは関数メンバーであるフィールドにoffsetofマクロを適用した結果は未定義です。関連項目:5.3.3節、Sizeof、5.7節、加算演算子、12.5節、フリーストア、およびISO C節7.1.6。

2
njsf

ああ、これはひどいです:

vector<MyObject> arr;
Fill(arr);
size_t size = arr.size();
for(size_t i = 1; i < size - 1; ++i)
{
  auto obj = arr[i];
  auto next = arr[i+1];
}

ここで、arrが空のユースケースを考えてみましょう。