サーチ…
Charは符号なしまたは符号付き
標準では、 char
が符号付きか符号なしかを指定していません。異なるコンパイラでは、異なる方法で実装するか、コマンドラインスイッチを使用してコンパイラを変更することができます。
積分型のサイズ
以下の型は、 整数型として定義されます 。
-
char
- 符号付き整数型
- 符号なし整数型
-
char16_t
とchar32_t
-
bool
-
wchar_t
除いてsizeof(char)
/ sizeof(signed char)
/ sizeof(unsigned char)
§3.9.1.1間で分割され、[basic.fundamental / 1]及び5.3.3.1 [expr.sizeof]、及び§ sizeof(bool)
、完全にインプリメンテーション定義され、最小サイズを持たないため、これらのタイプの最小サイズ要件は、標準のセクション3.9.1 [basic.fundamental]にあります。
char
サイズ
C ++標準のすべてのバージョンでは、5.3.3.1で、 sizeof
はunsigned char
、 signed char
、 char
( char
型がsigned
かunsigned
かを定義する実装です)に対して1
を指定します。
char
は、UTF-8コードユニットを格納するのに適した256の異なる値を表現するのに十分な大きさです。
符号付きおよび符号なし整数型のサイズ
標準では、§3.9.1.2で、 signed char
、 short int
、 int
、 long int
、およびlong long int
からなる標準符号付き整数型のリストで、各型は少なくとも先行するlong long int
それはリストにあります。さらに、§3.9.1.3で規定されているように、これらの型のそれぞれは、対応する標準の符号なし整数型 、 unsigned char
、 unsigned short int
、 unsigned int
、 unsigned long int
、およびunsigned long long int
を持ちます。対応する署名付きタイプさらに、§3.9.1.1で規定されているように、 char
はsigned char
とunsigned char
両方と同じサイズと位置合わせの必要条件を持っています。
C ++ 11より前のバージョンでは、 long long
とunsigned long long
は正式にC ++標準の一部ではありませんでした。しかし、Cへの導入後、C99では、多くのコンパイラがlong long
unsigned long long
整数型としてlong long
サポートlong long
れており、C型と同じ規則を持つ符号 unsigned long long
型の unsigned long long
型の unsigned long long
型がサポートlong long
れています。
したがって、標準では次のことが保証されています。
1 == sizeof(char) == sizeof(signed char) == sizeof(unsigned char)
<= sizeof(short) == sizeof(unsigned short)
<= sizeof(int) == sizeof(unsigned int)
<= sizeof(long) == sizeof(unsigned long)
<= sizeof(long long) == sizeof(unsigned long long)
各タイプの具体的な最小サイズは、標準によって与えられていません。代わりに、各タイプにはサポートできる値の最小範囲があります。これは§5.2.4.2.1のC標準から継承された§3.9.1.3で規定されています。各タイプの最小サイズは、必要とされる最小ビット数を決定することによって、この範囲から概算することができます。どのプラットフォームでも、実際にサポートされているタイプの範囲は、最小値より大きくなる可能性があることに注意してください。符号付きの型の場合、範囲は1の補数に対応し、より一般的に使用される2の補数には対応しないことに注意してください。これは、広範なプラットフォームが標準に準拠することを可能にするためです。
タイプ | 最小範囲 | 必要な最小ビット数 |
---|---|---|
signed char | -127~127( - (2 7 -1)〜(2 7 -1)) | 8 |
unsigned char | 0〜255(0〜2 8 -1) | 8 |
signed short | -32,767~32,767( - (2 15 -1)〜(2 15 -1)) | 16 |
unsigned short | 0〜65535(0〜2 16 -1) | 16 |
signed int | -32,767~32,767( - (2 15 -1)〜(2 15 -1)) | 16 |
unsigned int | 0〜65535(0〜2 16 -1) | 16 |
signed long | -2,147,483,647~2,147,483,647( - (2 31 -1)〜(2 31 -1)) | 32 |
unsigned long | 0〜4,294,967,295(0〜2 32 -1) | 32 |
タイプ | 最小範囲 | 必要な最小ビット数 |
---|---|---|
signed long long | -9,223,372,036,854,775,807 9,223,372,036,854,775,807に( - (2 63 - 1) - 1)(2〜63) | 64 |
unsigned long long | 0〜18,446,744,073,709,551,615(0〜2 64 -1) | 64 |
各タイプは最小サイズ要件よりも大きくできるため、実装間で型のサイズが異なる場合があります。これの最も顕著な例は、LLP64システム(64ビットWindowsなど)が32ビットints
とlong
を持ち、LP64システム(64ビットLinuxなど)がある64ビットデータモデルLP64とLLP64です。 32ビットint
および64ビットlong
このため、整数型はすべてのプラットフォームで固定幅と見なすことはできません。
固定幅の整数型が必要な場合は、 <cstdint>
ヘッダーの型を使用しますが、標準では、実装では、 int8_t
、 int16_t
、 int32_t
、 int64_t
、 intptr_t
、 uint8_t
、 uint16_t
、 uint32_t
、 uint64_t
およびuintptr_t
。
char16_t
とchar32_t
サイズ
char16_t
とchar32_t
のサイズは、 char16_t
で規定されているように実装定義されており、3.9.1.5節で規定されている。
char16_t
は、UTF-16コード単位を表すのに十分な大きさで、uint_least16_t
と同じサイズ、符号、および整列をuint_least16_t
ます。従って、少なくとも16ビットのサイズであることが要求される。char32_t
は、UTF-32コード単位を表すのに十分な大きさで、uint_least32_t
と同じサイズ、符号、および整列をuint_least32_t
ます。したがって、少なくとも32ビットのサイズであることが要求される。
bool
大きさ
bool
のサイズは実装定義であり、 1
もなくてもよい。
wchar_tのサイズ
§3.9.1.5で指定されているwchar_t
は、サポートされているロケールの中で最大の拡張文字セットのすべての個別コード単位を値の範囲で表すことができる特殊タイプです。これは、 基になる型として知られている他の整数型の1つと同じサイズ、符号、および整列を持ちます。この型のサイズは、5.3.3.1で規定されているように実装定義されており、例えば、少なくとも8,16、または32ビットであってもよい。たとえば、システムがUnicodeをサポートしている場合、 wchar_t
は少なくとも32ビットでなければなりません(このルールの例外はWindowsですwchar_t
は互換性のために16ビットです)。これはC90規格(ISO 9899:1990§4.1.5)から継承されたものであり、軽微な言い換えである。
実装に応じて、 wchar_t
のサイズはwchar_t
、または32ビットであることがよくありますが、必ずしもそうであるとは限りません。これらの最も一般的な例は次のとおりです。
- UnixおよびUnixライクなシステムでは、
wchar_t
は32ビットで、通常はUTF-32で使用されます。 - Windowsでは、
wchar_t
は16ビットで、UTF-16で使用されます。 - 8ビットのみをサポートするシステムでは、
wchar_t
は8ビットです。
Unicodeサポートが望まれる場合、使用することが推奨されるchar
UTF-8の、 char16_t
UTF-16、またはchar32_t
代わりに使用する、UTF-32 wchar_t
。
データモデル
前述のように、整数型の幅はプラットフォームによって異なる場合があります。最も一般的なモデルは次のとおりです。サイズはビット単位で指定します。
モデル | int | long | ポインタ |
---|---|---|---|
LP32(2/4/4) | 16 | 32 | 32 |
ILP32(4/4/4) | 32 | 32 | 32 |
LLP64(4/4/8) | 32 | 32 | 64 |
LP64(4/8/8) | 32 | 64 | 64 |
これらのモデルのうち、
- 16ビットWindowsはLP32を使用しました。
- 32ビット* nixシステム(Unix、Linux、Mac OSXなどのUnixライクなOS)とWindowsではILP32を使用しています。
- 64ビットWindowsはLLP64を使用します。
- 64ビット* nixシステムはLP64を使用します。
ただし、これらのモデルは、標準では特に言及されていません。
1バイトのビット数
C ++では、 バイトはchar
オブジェクトが占有する領域です。バイト内のビット数は、 CHAR_BIT
で定義され、少なくとも8である必要があるclimits
によって与えられます。ほとんどの現代システムは8ビットのバイトを持ち、POSIXではCHAR_BIT
が正確に8である必要がありますが、 CHAR_BIT
8より大きい、すなわち、単一バイトは、8,16,32、または64ビットから構成され得る。
ポインタの数値
reinterpret_cast
を使って整数へのポインタをキャストした結果は、実装定義ですが、 "...は、基礎となるマシンのアドレッシング構造を知っている人には驚かないことを意図しています。"
int x = 42;
int* p = &x;
long addr = reinterpret_cast<long>(p);
std::cout << addr << "\n"; // prints some numeric address,
// probably in the architecture's native address format
同様に、整数から変換されたポインタも実装定義されています。
ポインタを整数として格納する正しい方法は、 uintptr_t
型またはintptr_t
型を使用することです。
// `uintptr_t` was not in C++03. It's in C99, in <stdint.h>, as an optional type
#include <stdint.h>
uintptr_t uip;
// There is an optional `std::uintptr_t` in C++11
#include <cstdint>
std::uintptr_t uip;
C ++ 11は、 uintptr_t
(C99標準、6.3.2.3)の定義ではC99を指します。
void
への有効なポインタをこの型に変換してからvoid
へのポインタに変換し、その結果を元のポインタと比較するという性質を持つ符号なし整数型です。
現代のプラットフォームの大部分では、フラットなアドレス空間を想定することができますが、 uintptr_t
算術演算はchar *
算術演算と同等ですが、変換が可能な限り、 void *
をuintptr_t
するときには、 uintptr_t
からvoid *
にキャストバックするときは逆にしてください。
技術
XSI準拠(X / Open System Interfaces)システムでは、
intptr_t
型とuintptr_t
型が必要です 。それ以外の場合はオプションです 。C標準の意味では、関数はオブジェクトではありません。
uintptr_t
が関数ポインタを保持できることがC標準によって保証されていません。とにかく、POSIX(2.12.3)の準拠には以下が必要です:すべての関数ポインタ型はvoid型ポインタと同じ表現を持たなければならない。関数ポインタをvoid *に変換しても、その表現を変更してはならない。そのような変換から生じたvoid *値は、明示的キャストを使用して情報を失うことなく元の関数ポインタ型に変換することができます。
C99§7.18.1:
初期のuが存在しないか存在しない場合にのみ異なるtypedef名が定義されている場合、それらは6.2.5節に記述されている対応する符号付きおよび符号なし型を表すものとする。これらの対応する型のうちの1つを提供する実装は、他の型を提供しなければならない。
uintptr_t
は、符号付き整数で分かりやすいようにポインタのビットを処理したい場合に意味があります。
数値型の範囲
整数型の範囲は実装定義です。 <limits>
ヘッダーは、すべての基本型の最小値と最大値を提供するstd::numeric_limits<T>
テンプレートを提供します。これらの値は、 <climits>
および(> = C ++ 11) <cinttypes>
ヘッダーによってC標準によって提供される保証を満たしています。
-
std::numeric_limits<signed char>::min()
はSCHAR_MIN
と等しく、-127以下です。 -
std::numeric_limits<signed char>::max()
はSCHAR_MAX
と等しく、127以上です。 -
std::numeric_limits<unsigned char>::max()
はUCHAR_MAX
と等しく、これは255以上です。 -
std::numeric_limits<short>::min()
はSHRT_MIN
と等しく、SHRT_MIN
以下です。 -
std::numeric_limits<short>::max()
はSHRT_MAX
と等しく、32767以上です。 -
std::numeric_limits<unsigned short>::max()
はUSHRT_MAX
と等しく、65535以上です。 -
std::numeric_limits<int>::min()
はINT_MIN
と等しく、INT_MIN
以下です。 -
std::numeric_limits<int>::max()
はINT_MAX
と等しく、32767以上です。 -
std::numeric_limits<unsigned int>::max()
はUINT_MAX
と等しく、65535以上です。 -
std::numeric_limits<long>::min()
はLONG_MIN
に等しく、-2147483647以下です。 -
std::numeric_limits<long>::max()
はLONG_MAX
に等しく、2147483647以上です。 -
std::numeric_limits<unsigned long>::max()
はULONG_MAX
に等しく、4294967295以上です。
-
std::numeric_limits<long long>::min()
はLLONG_MIN
に等しく、-9223372036854775807以下です。 -
std::numeric_limits<long long>::max()
は、LLONG_MAX
と等しく、9223372036854775807以上です。 -
std::numeric_limits<unsigned long long>::max()
はULLONG_MAX
と等しく、これは18446744073709551615以上です。
浮動小数点型のためにT
、 max()
しながら、最大の有限値であるmin()
最小の正の正規化した値です。浮動小数点型には、実装定義でも、 <cfloat>
ヘッダを使用してC標準によって提供される特定の保証を満たす追加メンバが用意されています。
- メンバ
digits10
は、精度の小数点以下の桁数をdigits10
ます。-
std::numeric_limits<float>::digits10
はFLT_DIG
と等しく、少なくとも6です。 -
std::numeric_limits<double>::digits10
はDBL_DIG
に等しく、少なくとも10です。 -
std::numeric_limits<long double>::digits10
はLDBL_DIG
に等しく、少なくとも10です。
-
- メンバ
min_exponent10
は、最小の負のEであり、その結果、電力Eに対する10が正常である。-
std::numeric_limits<float>::min_exponent10
はFLT_MIN_10_EXP
に等しく、-37以下になります。 -
std::numeric_limits<double>::min_exponent10
はDBL_MIN_10_EXP
に等しく、-37以下になります。std::numeric_limits<long double>::min_exponent10
はLDBL_MIN_10_EXP
に等しく、最大-37です。
-
- メンバー
max_exponent10
は、パワーEに対する10が有限であるような最大Eである。-
std::numeric_limits<float>::max_exponent10
はFLT_MIN_10_EXP
に等しく、少なくとも37です。 -
std::numeric_limits<double>::max_exponent10
はDBL_MIN_10_EXP
に等しく、少なくとも37です。 -
std::numeric_limits<long double>::max_exponent10
はLDBL_MIN_10_EXP
に等しく、少なくとも37です。
-
- メンバー
is_iec559
が真の場合、そのタイプはIEC 559 / IEEE 754に準拠しているため、その範囲はその標準によって決定されます。
浮動小数点型の値表現
標準では、 long double
はfloat
以上の精度を提供するdouble
以上の精度を提供する必要があります。そのlong double
こと任意の値表すことができるdouble
しながら、表すことができるdouble
任意の値表すことができるfloat
表すことができます。ただし、表現の詳細は実装定義されています。
浮動小数点型T
場合、 std::numeric_limits<T>::radix
は、 T
の表現で使用されるstd::numeric_limits<T>::radix
指定します。
std::numeric_limits<T>::is_iec559
が真の場合、 T
の表現は、IEC 559 / IEEE 754で定義されているフォーマットの1つに一致します。
整数から符号付き整数への変換時にオーバーフローする
符号付き整数または符号なし整数のいずれかが符号付き整数型に変換され、その値が宛先型で表現できない場合、生成される値は実装定義です。例:
// Suppose that on this implementation, the range of signed char is -128 to +127 and
// the range of unsigned char is 0 to 255
int x = 12345;
signed char sc = x; // sc has an implementation-defined value
unsigned char uc = x; // uc is initialized to 57 (i.e., 12345 modulo 256)
列挙型の基礎となる型(したがってサイズ)
スコープのない列挙型に対して基になる型が明示的に指定されていない場合は、実装定義の方法で決定されます。
enum E {
RED,
GREEN,
BLUE,
};
using T = std::underlying_type<E>::type; // implementation-defined
しかし、 int
とunsigned int
両方が列挙のすべての値を表すことができない場合を除いて、標準では列挙型の基になる型がint
より大きくならないように要求しています。したがって、上記のコードでは、 T
はint
、 unsigned int
、またはshort
ですが、 long long
ではなく、いくつかの例を挙げることができます。
列挙型は基底型と同じサイズ( sizeof
によって返される)を持つことに注意してください。