web-dev-qa-db-ja.com

C++標準はint、long型のサイズをどのように述べていますか

基本的な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

私はあまり成功せずに、さまざまなアーキテクチャやコンパイラの下でcharshortintlongdoublefloat(およびその他のタイプ)のサイズを示す信頼できる情報を見つけることを試みました。

660
Jérôme

C++標準では、整数型のサイズをバイト単位では指定していませんが、保持できる必要がある最小範囲を指定しています。必要な範囲から最小サイズをビット数で推測できます。あなたはそれから最小バイト数を推測することができます、そしてそれは バイトのビット数を定義するCHAR_BITマクロの値

charに対するもう1つの制約は、そのサイズが常に1バイト、つまりCHAR_BITビット(したがって名前)であるということです。

最小範囲 規格で必要とされる (22ページ):

_ msdn _ :のデータ型と範囲

  1. signed char:-127から127(注、-128から127ではなく、これは1の補数および符号と大きさのプラットフォームに対応します)
  2. unsigned char:0から255
  3. "plain" charsigned charまたはunsigned charと同じ範囲、 実装定義
  4. signed short:-32767から32767
  5. unsigned short:0から65535
  6. signed int:-32767から32767
  7. unsigned int:0から65535
  8. signed long:-2147483647から2147483647
  9. unsigned long:0から4294967295
  10. signed long long:-9223372036854775807から9223372036854775807
  11. unsigned long long:0から18446744073709551615

C++(またはC)実装は、以下の条件を満たす限り、型のサイズをバイト数sizeof(type)で任意の値に定義できます。

  1. sizeof(type) * CHAR_BITは、必要な範囲を含むのに十分な高さのビット数に評価されます。
  2. 型の順序はまだ有効です(例: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();
654
Alex B

32ビットシステムの場合、「事実上の」標準はILP32です。つまり、intlong、およびpointerはすべて32ビットの量です。

64ビットシステムでは、主要なUnixのデファクトスタンダードはLP64です - longとpointerは64ビットです(ただしintは32ビットです)。 Windowsの64ビット標準はLLP64です - long longとpointerは64ビットです(ただしlongintはどちらも32ビットです)。

かつて、一部のUNIXシステムはILP64組織を使用していました。

これらの事実上の規格のどれもC規格(ISO/IEC 9899:1999)によって規定されていませんが、それはすべてそれによって許可されています。

そして、定義上、Perlのconfigureスクリプトのテストにもかかわらず、sizeof(char)1です。

CHAR_BITが8よりはるかに大きいマシン(Crays)があったことに注意してください。つまり、charintの両方が32ビットだったので、IIRC、sizeof(int)も1でした。

227

実際にはそのようなことはありません。現在のアーキテクチャでは、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です。ストレージと同じ配置要件があります。

あなたが望むなら、あなたは静的に(コンパイル時)これらの基本的な型のサイズを主張することができます。想定の大きさが変わった場合、コードを移植することを考えるよう人々に警告します。

87
John Leidegren

標準があります。

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ビットであることが保証されています。

79
yinyueyouge

固定サイズ型が必要な場合は、 stdint.h で定義されているuint32_t(符号なし整数32ビット)のような型を使用してください。それらは C99 で指定されています。

38
Ben

更新:C++ 11では、TR1の型が正式に標準になりました。

  • long long int
  • unsigned long long int

そして<cstdint>の "サイズ"タイプ

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (そして署名されていないもの)。

さらにあなたが得る:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • 未署名の対応物。

これらの型は、少なくとも指定されたビット数を持つ最小の整数型を表します。同様に、少なくとも指定されたビット数を持つ「最速」整数型があります。

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • 未署名のバージョン。

「速い」とは、実装によって異なります。それはすべての目的のために最速である必要はありません。

33
Brian Neal

C++標準 は次のように言っています。

3.9.1、§2:

「signed char」、「short int」、「int」、「long int」、および「long long int」の5つの符号付き整数型があります。このリストでは、各タイプは少なくともリスト内で先行するタイプと同じ量のストレージを提供します。普通の整数は、実行環境のアーキテクチャによって示唆される自然な大きさです(44)。他の符号付き整数型は特別なニーズを満たすために提供されています。

(44)つまり、 ヘッダ<climits>で定義されているように、INT_MINとINT_MAXの範囲内の任意の値を含むのに十分な大きさ

結論:それはあなたが取り組んでいるアーキテクチャによって異なります。他の仮定は誤りです。

18
Jérôme Radix

いや、タイプサイズの規格はありません。標準はそれだけを要求します:

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

あなたが固定サイズの変数が欲しいならあなたができる最善のことはこのようなマクロを使うことです:

#ifdef SYSTEM_X
  #define Word int
#else
  #define Word long int
#endif

その後、Wordを使って変数を定義できます。私がこれを好むわけではありませんが、 最も移植性の高い の方法です。

12
Emiliano

独自の「標準」を作成できるように、型の同義語を定義することが許可されています。

Sizeof(int)== 4のマシンでは、次のように定義できます。

typedef int int32;

int32 i;
int32 j;
...

そのため、実際にlong intのサイズが4である別のマシンにコードを転送すると、ただ1回出現するintを再定義できます。

typedef long int int32;

int32 i;
int32 j;
...
9
milan-j

浮動小数点数の場合、 標準があります(IEEE754) :浮動小数点は32ビットで、倍精度は64です。これはC++標準ではなくハードウェア標準なので、コンパイラは理論的に他のサイズにfloatおよびdoubleを定義できます実際には、私は違うものを使ったアーキテクチャを見たことがない。

8
Crashworks

標準があり、さまざまな標準ドキュメント(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 、これは標準で定義されています。

これがお役に立てば幸いです!

7
X-Istence
7
Andrew

あなたが使用することができます:

cout << "size of datatype = " << sizeof(datatype) << endl;

datatype = intlong intなど。どちらのデータ型を入力してもサイズがわかります。

7

さまざまなアーキテクチャやさまざまなコンパイラ用の組み込み型に関しては、コンパイラで次のコードを実行して、出力内容を確認してください。以下は私の 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
7
bjackfly

すでに述べたように、サイズは現在のアーキテクチャを反映するはずです。現在のコンパイラがどのように処理しているのかを知りたい場合は、limits.hを見てみるとよいでしょう。

4
John T

他の人が答えたように、 "標準"はすべての詳細を "実装定義"として残し、 "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を出力します。これらのスクリプトのいくつかを調べて、それらがどのように機能し、どのようにコイラー/システムの機能をプローブするのかを確認し、それらのリードに従うことができます。

2
C. M.

純粋な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;

}
1
user781847

あなたが言ったように - それは主にコンパイラとプラットフォームに依存します。これについては、ANSI規格、 http://home.att.net/~jackklein/c/inttypes.html を確認してください。

これがMicrosoftコンパイラのものです:Data Type Ranges

0
atVelu

質問者は浮動小数点についても尋ねましたが、ここでの他のすべての答えはほとんどもっぱら整数型に焦点を当てていることに気付きます。

C++標準では要求されていないと思いますが、最近の最も一般的なプラットフォーム用のコンパイラは、一般にIEEE 754標準に従って浮動小数点数に従います。この規格では、4種類のバイナリ浮動小数点(およびC++コンパイラでこれまでサポートされたことのないBCDフォーマット)を指定しています。

  • 半精度(binary16) - 11ビットの仮数、指数範囲は-14から15
  • 単精度(binary32) - 24ビットの仮数、指数範囲は-126から127
  • 倍精度(binary64) - 仮数53ビット、指数範囲は-1022から1023
  • 4倍精度(binary128) - 仮数113ビット、指数範囲は-16382から16383

では、これはどのようにC++型にマッピングされるのでしょうか。一般的にfloatは単精度を使います。したがって、sizeof(float) = 4doubleは倍精度を使用し(これがdoubleの名前の由来であると信じています)、そしてlong doubleは倍精度または4倍精度(私のシステムでは4倍精度ですが、32ビットシステムでは2倍精度です)のいずれかです。私は、半精度浮動小数点を提供するコンパイラを知りません。

要約すると、これは通常のことです。

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8または16
0
celticminstrel

Alex 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ビットシステムでもこれらを使用する傾向があり、拡張/変更があります。詳細についてはこれを参照してください。

http://en.cppreference.com/w/cpp/language/types

0
JCoder
unsigned char bits = sizeof(X) << 3;

ここでXcharintlongなどです。Xのサイズはビットで与えられます。

0
user3154672