基本的なC++型のサイズに関する詳細な情報を探しています。私はそれがアーキテクチャ(16ビット、32ビット、64ビット)とコンパイラに依存することを知っています。
しかし、C++の標準はありますか?
32ビットアーキテクチャでVisual Studio 2008を使用しています。これは私が得るものです:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double: 8 bytes
私はあまり成功せずに、さまざまなアーキテクチャやコンパイラの下でchar
、short
、int
、long
、double
、float
(およびその他のタイプ)のサイズを示す信頼できる情報を見つけることを試みました。
C++標準では、整数型のサイズをバイト単位では指定していませんが、保持できる必要がある最小範囲を指定しています。必要な範囲から最小サイズをビット数で推測できます。あなたはそれから最小バイト数を推測することができます、そしてそれは バイトのビット数を定義するCHAR_BIT
マクロの値 。
char
に対するもう1つの制約は、そのサイズが常に1バイト、つまりCHAR_BIT
ビット(したがって名前)であるということです。
最小範囲 規格で必要とされる (22ページ):
_ msdn _ :のデータ型と範囲
signed char
:-127から127(注、-128から127ではなく、これは1の補数および符号と大きさのプラットフォームに対応します)unsigned char
:0から255char
:signed char
またはunsigned char
と同じ範囲、 実装定義signed short
:-32767から32767unsigned short
:0から65535signed int
:-32767から32767unsigned int
:0から65535signed long
:-2147483647から2147483647unsigned long
:0から4294967295signed long long
:-9223372036854775807から9223372036854775807unsigned long long
:0から18446744073709551615C++(またはC)実装は、以下の条件を満たす限り、型のサイズをバイト数sizeof(type)
で任意の値に定義できます。
sizeof(type) * CHAR_BIT
は、必要な範囲を含むのに十分な高さのビット数に評価されます。sizeof(int) <= sizeof(long)
)。実際の実装固有の範囲は、Cの<limits.h>
ヘッダー、またはC++の<climits>
(またはさらに良いことには、std::numeric_limits
ヘッダーのテンプレート化された<limits>
)にあります。
たとえば、これはint
の最大範囲を見つける方法です。
C:
#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;
C++ :
#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();
32ビットシステムの場合、「事実上の」標準はILP32です。つまり、int
、long
、およびpointerはすべて32ビットの量です。
64ビットシステムでは、主要なUnixのデファクトスタンダードはLP64です - long
とpointerは64ビットです(ただしint
は32ビットです)。 Windowsの64ビット標準はLLP64です - long long
とpointerは64ビットです(ただしlong
とint
はどちらも32ビットです)。
かつて、一部のUNIXシステムはILP64組織を使用していました。
これらの事実上の規格のどれもC規格(ISO/IEC 9899:1999)によって規定されていませんが、それはすべてそれによって許可されています。
そして、定義上、Perlのconfigureスクリプトのテストにもかかわらず、sizeof(char)
は1
です。
CHAR_BIT
が8よりはるかに大きいマシン(Crays)があったことに注意してください。つまり、char
とint
の両方が32ビットだったので、IIRC、sizeof(int)
も1でした。
実際にはそのようなことはありません。現在のアーキテクチャでは、std::size_t
が符号なしのネイティブ整数サイズを表すことを期待できることがよくあります。すなわち16ビット、32ビット、または64ビットですが、この回答へのコメントで指摘されているように必ずしもそうとは限りません。
他のすべての組み込み型に関する限り、それは本当にコンパイラに依存します。これは、最新のC++標準の現在の作業中の草案から抜粋した2つの抜粋です。
Signed char、short int、int、long int、およびlong long intの5つの標準的な符号付き整数型があります。このリストでは、各タイプは少なくともリスト内で先行するタイプと同じ量のストレージを提供します。
それぞれの標準符号付き整数型には、対応する(ただし異なる)標準の符号なし整数型があります。unsigned char、unsigned short int、unsigned int、unsigned long int、およびunsigned long long intです。ストレージと同じ配置要件があります。
あなたが望むなら、あなたは静的に(コンパイル時)これらの基本的な型のサイズを主張することができます。想定の大きさが変わった場合、コードを移植することを考えるよう人々に警告します。
標準があります。
C90標準はそれを要求します
sizeof(short) <= sizeof(int) <= sizeof(long)
C99標準はそれを要求します
sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
これがC99の仕様です 。異なる整数型のサイズについては、22ページを参照してください。
これは、Windowsプラットフォーム用のint型のサイズ(ビット)です。
Type C99 Minimum Windows 32bit
char 8 8
short 16 16
int 16 32
long 32 32
long long 64 64
移植性に関心がある場合、またはタイプの名前にサイズを反映させる場合は、ヘッダー<inttypes.h>
を見れば、次のマクロが利用可能です。
int8_t
int16_t
int32_t
int64_t
int8_t
は8ビット、int16_t
は16ビットであることが保証されています。
更新:C++ 11では、TR1の型が正式に標準になりました。
そして<cstdint>
の "サイズ"タイプ
さらにあなたが得る:
これらの型は、少なくとも指定されたビット数を持つ最小の整数型を表します。同様に、少なくとも指定されたビット数を持つ「最速」整数型があります。
「速い」とは、実装によって異なります。それはすべての目的のために最速である必要はありません。
C++標準 は次のように言っています。
3.9.1、§2:
「signed char」、「short int」、「int」、「long int」、および「long long int」の5つの符号付き整数型があります。このリストでは、各タイプは少なくともリスト内で先行するタイプと同じ量のストレージを提供します。普通の整数は、実行環境のアーキテクチャによって示唆される自然な大きさです(44)。他の符号付き整数型は特別なニーズを満たすために提供されています。
(44)つまり、 ヘッダ
<climits>
で定義されているように、INT_MINとINT_MAXの範囲内の任意の値を含むのに十分な大きさ。
結論:それはあなたが取り組んでいるアーキテクチャによって異なります。他の仮定は誤りです。
いや、タイプサイズの規格はありません。標準はそれだけを要求します:
sizeof(short int) <= sizeof(int) <= sizeof(long int)
あなたが固定サイズの変数が欲しいならあなたができる最善のことはこのようなマクロを使うことです:
#ifdef SYSTEM_X
#define Word int
#else
#define Word long int
#endif
その後、Wordを使って変数を定義できます。私がこれを好むわけではありませんが、 最も移植性の高い の方法です。
独自の「標準」を作成できるように、型の同義語を定義することが許可されています。
Sizeof(int)== 4のマシンでは、次のように定義できます。
typedef int int32;
int32 i;
int32 j;
...
そのため、実際にlong intのサイズが4である別のマシンにコードを転送すると、ただ1回出現するintを再定義できます。
typedef long int int32;
int32 i;
int32 j;
...
浮動小数点数の場合、 標準があります(IEEE754) :浮動小数点は32ビットで、倍精度は64です。これはC++標準ではなくハードウェア標準なので、コンパイラは理論的に他のサイズにfloatおよびdoubleを定義できます実際には、私は違うものを使ったアーキテクチャを見たことがない。
標準があり、さまざまな標準ドキュメント(ISO、ANSI、その他)で指定されています。
ウィキペディアには、さまざまなタイプとそれらが保存できる最大数を説明する素晴らしいページがあります: 整数in Computer Science。
ただし、標準のC++コンパイラを使用しても、次のコードスニペットを使用すると比較的簡単に見つけることができます。
#include <iostream>
#include <limits>
int main() {
// Change the template parameter to the various different types.
std::cout << std::numeric_limits<int>::max() << std::endl;
}
std :: numeric_limits のドキュメントは Roguewave にあります。さまざまな制限を見つけるために呼び出すことができる他のコマンドが多数含まれています。これは、サイズを伝える任意のタイプ(std :: streamsizeなど)で使用できます。
ジョンの答えには、それらが保持されることが保証されているため、最良の説明が含まれています。どのプラットフォームを使用していても、各タイプに含める必要があるビット数について詳しく説明する別の優れたページがあります: int types 、これは標準で定義されています。
これがお役に立てば幸いです!
1)記事「 64ビットプログラム開発の忘れられていた問題 」の表N1
2) " データモデル "
あなたが使用することができます:
cout << "size of datatype = " << sizeof(datatype) << endl;
datatype = int
、long int
など。どちらのデータ型を入力してもサイズがわかります。
さまざまなアーキテクチャやさまざまなコンパイラ用の組み込み型に関しては、コンパイラで次のコードを実行して、出力内容を確認してください。以下は私の Ubuntu 13.04 (Raring Ringtail)64ビットg ++ 4.7.3の出力です。また、以下に答えられたことに注意してください。これが、出力がそのように順序付けられている理由です。
「signed char、short int、int、long int、およびlong long intの5つの標準的な符号付き整数型があります。このリストでは、各型は少なくともリストの前にあるものと同じ容量を提供します。」
#include <iostream>
int main ( int argc, char * argv[] )
{
std::cout<< "size of char: " << sizeof (char) << std::endl;
std::cout<< "size of short: " << sizeof (short) << std::endl;
std::cout<< "size of int: " << sizeof (int) << std::endl;
std::cout<< "size of long: " << sizeof (long) << std::endl;
std::cout<< "size of long long: " << sizeof (long long) << std::endl;
std::cout<< "size of float: " << sizeof (float) << std::endl;
std::cout<< "size of double: " << sizeof (double) << std::endl;
std::cout<< "size of pointer: " << sizeof (int *) << std::endl;
}
size of char: 1
size of short: 2
size of int: 4
size of long: 8
size of long long: 8
size of float: 4
size of double: 8
size of pointer: 8
すでに述べたように、サイズは現在のアーキテクチャを反映するはずです。現在のコンパイラがどのように処理しているのかを知りたい場合は、limits.h
を見てみるとよいでしょう。
他の人が答えたように、 "標準"はすべての詳細を "実装定義"として残し、 "char"型の幅は "char_bis"以上で、 "char <= short <= int <= long <と書いてあるだけです。 (longとdoubleはIEEEの浮動小数点規格とほぼ一致しており、long doubleは通常doubleと同じですが、より新しい実装ではもっと大きくなる可能性があります)。
あまり具体的で厳密な値を持たない理由の一部は、C/C++のような言語が多数のハードウェアプラットフォームに移植できるように設計されているためです。「char」ワードサイズが4ビットのコンピュータシステムを含みます。家庭用コンピュータの平均的なユーザーが晒されている「8/16/32/64ビット」コンピュータ以外の値、または7ビット、あるいはさらには何らかの値。 (ここでのワードサイズとは、システムが通常何ビット幅で動作しているかを意味します。繰り返しますが、家庭用コンピュータのユーザーが期待するように必ずしも8ビットではありません。)
特定のビット数のオブジェクト(整数値を表す一連のビットという意味で)が本当に必要な場合は、ほとんどのコンパイラでそれを指定する方法があります。しかし、これは一般的には移植性がありません。Ame社製のコンパイラ間であっても異なるプラットフォーム用です。標準や慣習(特にlimits.hなど)は一般的なものであるため、ほとんどのコンパイラは特定の範囲の値に最適な型を決定するためのサポートを提供しますが、使用されるビット数についてはサポートしません。 (つまり、0から127の間の値を保持する必要があることがわかっている場合は、コンパイラが8ビットの "int8"タイプをサポートしていると判断できます。 7ビットに完全に一致する "int7"型
注意:多くのUn * xソースパッケージは "./configure"スクリプトを使用しました。これはコンパイラ/システムの機能を調べ、適切なMakefileとconfig.hを出力します。これらのスクリプトのいくつかを調べて、それらがどのように機能し、どのようにコイラー/システムの機能をプローブするのかを確認し、それらのリードに従うことができます。
純粋なC++ソリューションに興味がある場合は、テンプレートとC++標準コードのみを使用して、コンパイル時にそれらのビットサイズに基づいて型を定義しました。これにより、ソリューションはコンパイラー間で移植可能になります。
その背後にある考え方は非常に簡単です。char、int、short、long、long(符号付きおよび符号なしのバージョン)型を含むリストを作成し、リストをスキャンして、numeric_limitsテンプレートを使用して与えられたサイズの型を選択します。
このヘッダを含めると、8種類のstdtype :: int8、stdtype :: int16、stdtype :: int32、stdtype :: int64、stdtype :: uint8、stdtype :: uint16、stdtype :: uint32、stdtype :: uint64が得られます。
いくつかの型を表現できない場合は、そのヘッダで宣言されているstdtype :: null_typeに評価されます。
以下のコードISは、保証なしで提供されています。2重チェックしてください。
私は新しいATメタプログラミングができました。編集してこのコードを修正してください。
DevC++でテスト済み(したがって、gccバージョンは3.5前後)
#include <limits>
namespace stdtype
{
using namespace std;
/*
* THIS IS THE CLASS USED TO SEMANTICALLY SPECIFY A NULL TYPE.
* YOU CAN USE WHATEVER YOU WANT AND EVEN DRIVE A COMPILE ERROR IF IT IS
* DECLARED/USED.
*
* PLEASE NOTE that C++ std define sizeof of an empty class to be 1.
*/
class null_type{};
/*
* Template for creating lists of types
*
* T is type to hold
* S is the next type_list<T,S> type
*
* Example:
* Creating a list with type int and char:
* typedef type_list<int, type_list<char> > test;
* test::value //int
* test::next::value //char
*/
template <typename T, typename S> struct type_list
{
typedef T value;
typedef S next;
};
/*
* Declaration of template struct for selecting a type from the list
*/
template <typename list, int b, int ctl> struct select_type;
/*
* Find a type with specified "b" bit in list "list"
*
*
*/
template <typename list, int b> struct find_type
{
private:
//Handy name for the type at the head of the list
typedef typename list::value cur_type;
//Number of bits of the type at the head
//CHANGE THIS (compile time) exp TO USE ANOTHER TYPE LEN COMPUTING
enum {cur_type_bits = numeric_limits<cur_type>::digits};
public:
//Select the type at the head if b == cur_type_bits else
//select_type call find_type with list::next
typedef typename select_type<list, b, cur_type_bits>::type type;
};
/*
* This is the specialization for empty list, return the null_type
* OVVERRIDE this struct to ADD CUSTOM BEHAVIOR for the TYPE NOT FOUND case
* (ie search for type with 17 bits on common archs)
*/
template <int b> struct find_type<null_type, b>
{
typedef null_type type;
};
/*
* Primary template for selecting the type at the head of the list if
* it matches the requested bits (b == ctl)
*
* If b == ctl the partial specified templated is evaluated so here we have
* b != ctl. We call find_type on the next element of the list
*/
template <typename list, int b, int ctl> struct select_type
{
typedef typename find_type<typename list::next, b>::type type;
};
/*
* This partial specified templated is used to select top type of a list
* it is called by find_type with the list of value (consumed at each call)
* the bits requested (b) and the current type (top type) length in bits
*
* We specialice the b == ctl case
*/
template <typename list, int b> struct select_type<list, b, b>
{
typedef typename list::value type;
};
/*
* These are the types list, to avoid possible ambiguity (some weird archs)
* we kept signed and unsigned separated
*/
#define UNSIGNED_TYPES type_list<unsigned char, \
type_list<unsigned short, \
type_list<unsigned int, \
type_list<unsigned long, \
type_list<unsigned long long, null_type> > > > >
#define SIGNED_TYPES type_list<signed char, \
type_list<signed short, \
type_list<signed int, \
type_list<signed long, \
type_list<signed long long, null_type> > > > >
/*
* These are acutally typedef used in programs.
*
* Nomenclature is [u]intN where u if present means unsigned, N is the
* number of bits in the integer
*
* find_type is used simply by giving first a type_list then the number of
* bits to search for.
*
* NB. Each type in the type list must had specified the template
* numeric_limits as it is used to compute the type len in (binary) digit.
*/
typedef find_type<UNSIGNED_TYPES, 8>::type uint8;
typedef find_type<UNSIGNED_TYPES, 16>::type uint16;
typedef find_type<UNSIGNED_TYPES, 32>::type uint32;
typedef find_type<UNSIGNED_TYPES, 64>::type uint64;
typedef find_type<SIGNED_TYPES, 7>::type int8;
typedef find_type<SIGNED_TYPES, 15>::type int16;
typedef find_type<SIGNED_TYPES, 31>::type int32;
typedef find_type<SIGNED_TYPES, 63>::type int64;
}
あなたが言ったように - それは主にコンパイラとプラットフォームに依存します。これについては、ANSI規格、 http://home.att.net/~jackklein/c/inttypes.html を確認してください。
これがMicrosoftコンパイラのものです:Data Type Ranges。
質問者は浮動小数点についても尋ねましたが、ここでの他のすべての答えはほとんどもっぱら整数型に焦点を当てていることに気付きます。
C++標準では要求されていないと思いますが、最近の最も一般的なプラットフォーム用のコンパイラは、一般にIEEE 754標準に従って浮動小数点数に従います。この規格では、4種類のバイナリ浮動小数点(およびC++コンパイラでこれまでサポートされたことのないBCDフォーマット)を指定しています。
では、これはどのようにC++型にマッピングされるのでしょうか。一般的にfloat
は単精度を使います。したがって、sizeof(float) = 4
。 double
は倍精度を使用し(これがdouble
の名前の由来であると信じています)、そしてlong double
は倍精度または4倍精度(私のシステムでは4倍精度ですが、32ビットシステムでは2倍精度です)のいずれかです。私は、半精度浮動小数点を提供するコンパイラを知りません。
要約すると、これは通常のことです。
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8または16Alex BよりC++標準では、整数型のサイズをバイト単位では指定していませんが、保持できる必要がある最小範囲を指定しています。必要な範囲から最小サイズをビット数で推測できます。あなたはそれからバイトで最小サイズを推論することができます、そして、バイトのビット数を定義するCHAR_BITマクロの値(最もあいまいなプラットフォームを除いてすべてそれは8であり、それは8より小さくてはいけません)。
Charのもう1つの制約は、そのサイズが常に1バイト、つまりCHAR_BITビット(したがって名前)であるということです。
規格(22ページ)で必要とされる最小範囲は以下のとおりです。
とMSDNのデータ型の範囲:
signed char:-127〜127(注、-128〜127ではありません。これは1の補数プラットフォームに対応しています)unsigned char:0〜255 "plain" char:-127〜127または0〜255(デフォルトのchar符号付きによる) short:-32767〜32767 unsigned short:0〜65535 signed int:-32767〜32767 unsigned int:0〜65535 signed long:-2147483647〜2147483647 unsigned long:0〜4294967295 signed long:-9223372036854775807〜9223372036854775807 unsigned long 0〜18446744073709551615 C++(またはC)の実装では、バイト単位の型のサイズsizeof(type)は、次の値であれば、任意の値に定義できます。
式sizeof(type)* CHAR_BITは必要な範囲を含むのに十分なビット数に評価され、typeの順序は依然として有効です(例:sizeof(int)<= sizeof(long))。実際の実装固有の範囲は、Cのヘッダー、またはC++(またはさらに良いことには、ヘッダー内のテンプレート化されたstd :: numeric_limits)にあります。
たとえば、これはintの最大範囲を見つける方法です。
子:
#include <limits.h>
const int min_int = INT_MIN;
const int max_int = INT_MAX;
C++:
#include <limits>
const int min_int = std::numeric_limits<int>::min();
const int max_int = std::numeric_limits<int>::max();
これは正しいですが、あなたは正しいとも言っていました:char:1バイトshort:2バイトint:4バイト長:4バイトfloat:4バイトdouble:8バイト
32ビットアーキテクチャは依然としてデフォルトで最も使用されており、メモリが利用できなくなる32ビット以前の時代からこれらの標準サイズを維持していたため、下位互換性と標準化のために同じままでした。 64ビットシステムでもこれらを使用する傾向があり、拡張/変更があります。詳細についてはこれを参照してください。
unsigned char bits = sizeof(X) << 3;
ここでX
はchar
、int
、long
などです。X
のサイズはビットで与えられます。