web-dev-qa-db-ja.com

`long`は少なくとも32ビットであることが保証されていますか?

C++標準を読んだことで、C++の積分基本型のサイズは次のとおりであることが常に理解されていました。

sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

私はこれを3.9.1/2から推測しました:

  1. 符号付き整数には、「signed char」、「short int」、「int」、「longint」の4つのタイプがあります。このリストでは、各タイプは、少なくともリスト内でその前にあるものと同じ量のストレージを提供します。プレーンintは、実行環境のアーキテクチャによって提案される自然なサイズを持っています

さらに、charのサイズは3.9.1 /によって次のように記述されています。

  1. [...]実装の基本的な文字セットのメンバーを格納するのに十分な大きさ。

1.7/1は、これをより具体的な用語で定義しています。

  1. C++メモリモデルの基本的なストレージユニットはバイトです。バイトは、少なくとも基本実行文字セットのメンバーを含むのに十分な大きさであり、連続するビットシーケンスで構成され、その数は実装によって定義されます。

これは私を次の結論に導きます:

1 == sizeof(char) <= sizeof(short int) <= sizeof(int) <= sizeof(long int)

ここで、sizeofは、タイプのバイト数を示します。さらに、1バイトに含まれるビット数は実装によって定義されます。私たちのほとんどはおそらく8ビットバイトの処理に慣れていますが、標準では1バイトにnビットがあるとされています。


この投稿 で、Alf P.Steinbachは次のように述べています。

longは(少なくとも)32ビットが保証されています。

これは、標準に準拠したC++の基本型のサイズを理解しているすべてのことに直面しています。通常、私は初心者が間違っているとしてこの声明を軽視しますが、これはアルフだったので、さらに調査する価値があると判断しました。

それで、あなたは何と言いますか?規格によってlongは少なくとも32ビットであることが保証されていますか?その場合、この保証がどのように行われるかについて具体的に説明してください。見えないだけです。

  1. C++標準では、C++を知るには、C(1.2/1)を知っている必要があると具体的に述べられています。 1

  2. C++標準では、longLONG_MIN-LONG_MAXに対応できる値の最小制限が暗黙的に定義されています。 2

したがって、longがどれほど大きくても、LONG_MINをLONG_MAXに保持するのに十分な大きさである必要があります。

しかし、Alfなどは固有であり、longは少なくとも32ビットでなければなりません。これが私が確立しようとしていることです。 C++標準では、バイトのビット数が指定されていないことが明示されています(4、8、16、42の場合があります)。したがって、接続は、数値LONG_MIN-LONG_MAXに対応できる状態から少なくとも32ビット?


(1)1.2/1:この文書の適用には、以下の参照文書が不可欠です。日付のある参照については、引用されたエディションのみが適用されます。日付のない参照については、参照されたドキュメントの最新版(修正を含む)が適用されます。

  • ISO/IEC 2382(すべての部品)、情報技術–語彙
  • ISO/IEC 9899:1999、プログラミング言語– C
  • ISO/IEC 10646-1:2000、情報技術–国際符号化文字集合(UCS)–パート1:アーキテクチャと基本的な多言語面

(2)<climits>で次のように定義されています。

LONG_MIN -2147483647 // -(2^31 - 1)
LONG_MAX +2147483647 //   2^31 - 1
51
John Dibling

答えは間違いなくイエスです。私のOPとすべてのコメントを読んで、その理由を正確に理解してください。ただし、ここに短いバージョンがあります。これについて疑問や疑問がある場合は、スレッド全体とすべてのコメントを読むことをお勧めします。それ以外の場合は、これをtrueとして受け入れます。

  1. C++標準には、_LONG_MIN_および_LONG_MAX_の定義を含む、C標準の一部が含まれています。
  2. _LONG_MIN_は_-2147483647_以下として定義されます
  3. _LONG_MAX_は_+2147483647_以上として定義されます
  4. C++では、整数型は基底表現でバイナリに格納されます
  5. _-2147483647_と_+2147483647_をバイナリで表すには、32ビットが必要です。
  6. C++ longは、最小範囲_LONG_MIN_から_LONG_MAX_を表すことができることが保証されています。

したがって、longは少なくとも32ビットである必要があります1

編集:

_LONG_MIN_および_LONG_MAX_の値は、セクション§5.2.4.2.1のC標準(ISO/IEC 9899:TC3)で指定された大きさです。

[...]それらの実装定義値は、同じ符号で、示されている値と同じかそれ以上の大きさ[...](絶対値)でなければなりません[...]

_— minimum value for an object of type long int
LONG_MIN -2147483647 // -(2 ^ 31 - 1)
— maximum value for an object of type long int
LONG_MAX +2147483647 // 2 ^ 31 - 1
_

12ビット:バイトは必ずしも8ビットではないため、これはsizeof (long) >= 4を意味するものではありません。標準によれば、バイトは指定されていない(プラットフォームで定義された)ビット数です。ほとんどの読者はこれを奇妙に感じるでしょうが、_CHAR_BIT_が16または32である実際のハードウェアがあります。

16
John Dibling

C++は、C標準で定義されている制限を使用します(C++:18.3.2(c.limits)、C:5.2.4.2.1):

_LONG_MIN -2147483647 // -(2^31 - 1)
LONG_MAX +2147483647 //   2^31 - 1
_

したがって、longは少なくとも32ビットであることが保証されます。

また、_LONG_MIN_/_LONG_MAX_がlongで表現できるかどうかについて、長い遠回りのルートをたどりたい場合は、18.3.1.2(numeric.limits.members)を参照する必要があります。 C++標準:

_static constexpr T min() throw(); // Equivalent to CHAR_MIN, SHRT_MIN, FLT_MIN, DBL_MIN, etc.
static constexpr T max() throw(); // Equivalent to CHAR_MAX, SHRT_MAX, FLT_MAX, DBL_MAX, etc.
_

脚注をコメントに移動したので、標準に表示されているものとは正確には異なります。しかし、それは基本的にstd::numeric_limits<long>::min()==LONG_MIN==(long)LONG_MINstd::numeric_limits<long>::max()==LONG_MAX==(long)LONG_MAXを意味します。

したがって、C++標準では(符号付き)負の数値のビット単位の表現は指定されていませんが、2の補数であり、合計32ビットのストレージが必要であるか、明示的な符号ビットがある必要があります。 32ビットのストレージもあります。

36
MSN

C++標準では、<climits>の内容はCヘッダー<limits.h>(ISO C++ 03ドキュメントの18.2.2)と同じであると記載されています。

残念ながら、C++ 98より前に存在していたC標準(つまりC90)のコピーはありませんが、C99(セクション5.2.4.2.1)では、<limits.h>に少なくともこの最小値が必要です。 。これは、C99がlong longタイプを追加することを除いて、C90から変更されたとは思いません。

— minimum value for an object of type long int

LONG_MIN -2147483647 // −(2^31 − 1)

— maximum value for an object of type long int

LONG_MAX +2147483647 // 2^31 − 1

— maximum value for an object of type unsigned long int

ULONG_MAX 4294967295 // 2^32 − 1

— minimum value for an object of type long long int

LLONG_MIN -9223372036854775807 // −(2^63− 1)
7
wkl

しかし、Alfやその他の人々は、longは少なくとも32ビットでなければならないことを明確にしています。これが私が確立しようとしていることです。 C++標準では、1バイトのビット数が指定されていないことが明示されています。 4、8、16、42の可能性があります...では、LONG_MIN-LONG_MAXの数値を収容できる状態から、少なくとも32ビットになるまでの接続はどのように行われるのでしょうか。

少なくともその数ビットパターンを取得するには、値表現に32ビットが必要です。また、C++では整数のバイナリ表現が必要なため(標準ではその趣旨の明示的な言語、§3.9.1/ 7)、Q.E.D。

はい、C++標準では、1バイトのビット数が指定されていないことが明示されています。 longのビット数も指定されていません。

数値に下限を設定することは、それを指定することではありません

C++標準では、次のように述べています。

1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long).

それは、事実上、別の場所で、C標準を含めることによって次のように述べています。

CHAR_BITS >= 8; SHORT_BITS >= 16; INT_BITS >= 16; LONG_BITS >= 32

(ただし、AFAIK、識別子SHORT_BITS、INT_BITS、およびLONG_BITSは存在せず、これらの制限は、タイプの最小値の要件によって推測されます。)

これは、数学的には、(longなどの)LONG_MIN..LONG_MAX範囲のすべての値をエンコードするために特定のビット数が必要であるという事実に基づいています。

最後に、shorts、ints、およびlongsはすべて、整数個の文字で構成されている必要があります。 sizeof()は常に整数値を報告します。また、メモリをcharごとに繰り返すには、すべてのビットにアクセスする必要があり、これにはいくつかの実用的な制限があります。

これらの要件は決して矛盾していません。要件を満たす任意のサイズで問題ありません。

ずっと前に、36ビットのネイティブワードサイズのマシンがありました。 C++コンパイラをそれらに移植する場合、charに9ビット、shortとintの両方に18ビット、longに36ビットを含めることを法的に決定できます。また、今日の一般的な32ビットシステムではintに32ビットを含めることができるのと同じ理由で、これらの各タイプに36ビットを含めることを法的に決定することもできます。 64ビット文字を使用する実際の実装があります。

C++ FAQ Lite のセクション26.1-6および29.5も参照してください。

6
Karl Knechtel