我正在寻找关于基本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(以及其他我没有想到的类型)的大小的可靠信息,但没有多大成功。


当前回答

实际上没有这样的事情。通常,std::size_t表示当前体系结构上的无符号本机整数大小。即16位、32位或64位,但并不总是如此,就像这个答案的评论中指出的那样。

至于所有其他内置类型,它实际上取决于编译器。以下是摘自最新c++标准的当前工作草案的两段摘录:

There are five standard signed integer types : signed char, short int, int, long int, and long long int. In this list, each type provides at least as much storage as those preceding it in the list. For each of the standard signed integer types, there exists a corresponding (but different) standard unsigned integer type: unsigned char, unsigned short int, unsigned int, unsigned long int, and unsigned long long int, each of which occupies the same amount of storage and has the same alignment requirements.

如果您愿意,您可以静态(编译时)断言这些基本类型的sizeof。如果假设的大小发生变化,它会提醒人们考虑移植您的代码。

其他回答

如果您对纯c++解决方案感兴趣,我使用模板和仅c++标准代码在编译时根据位大小定义类型。 这使得解决方案可以跨编译器移植。

背后的想法很简单:创建一个包含类型char, int, short, long, long long(有符号和无符号版本)的列表,然后扫描列表,并使用numeric_limits模板选择具有给定大小的类型。

包括这个头,你得到8类型stdtype::int8, stdtype::int16, stdtype::int32, stdtype::int64, stdtype::uint8, stdtype::uint16, stdtype::uint32, stdtype::uint64。

如果某些类型不能被表示,它将被计算为stdtype::null_type,也在该头文件中声明。

以下代码没有保修,请仔细检查。 我也是元编程的新手,请随意编辑和更正此代码。 使用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;

}

根据大小有四种类型的整数:

短整数:2字节 长整数:4字节 Long Long integer: 8字节 整数:取决于编译器(16位、32位或64位)

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

其中X是char,int,long等。会得到X的比特大小。

c++标准没有以字节为单位指定整型的大小,但它指定了它们必须能够容纳的最小范围。您可以从所需的范围推断出最小大小(以位为单位)。您可以从该值和CHAR_BIT宏的值推断出最小的字节大小,CHAR_BIT宏定义了字节中的位数(除了最晦涩的平台之外,在所有平台中它都是8,而且不能小于8)。

char的另一个限制是它的大小总是1字节,或CHAR_BIT位(因此得名)。

标准(第22页)要求的最小范围是:

MSDN上的数据类型范围:

signed char: -127 to 127 (note, not -128 to 127; this accommodates 1's-complement platforms) unsigned char: 0 to 255 "plain" char: -127 to 127 or 0 to 255 (depends on default char signedness) signed short: -32767 to 32767 unsigned short: 0 to 65535 signed int: -32767 to 32767 unsigned int: 0 to 65535 signed long: -2147483647 to 2147483647 unsigned long: 0 to 4294967295 signed long long: -9223372036854775807 to 9223372036854775807 unsigned long long: 0 to 18446744073709551615 A C++ (or C) implementation can define the size of a type in bytes sizeof(type) to any value, as long as

表达式sizeof(type) * CHAR_BIT计算为足够包含所需范围的比特数,并且 类型的顺序仍然有效(例如sizeof(int) <= sizeof(long))。 实际的特定于实现的范围可以在C或c++的header中找到(或者更好的是,在header中找到模板化的std::numeric_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();

这是正确的,但是,你说的也对: Char: 1字节 短:2字节 Int: 4字节 Long: 4字节 浮点数:4字节 Double: 8字节

因为32位体系结构仍然是默认的,也是最常用的,并且自从前32位时代内存可用性较低以来,他们就一直保持这些标准大小,为了向后兼容和标准化,它保持不变。即使是64位系统也倾向于使用这些并进行扩展/修改。 更多信息请参考:

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

更新:c++ 11将TR1中的类型正式引入标准:

Long Long int Unsigned long long int

以及<cstdint>中的"size "类型

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 加上无符号的版本。

“快”意味着什么,如果有的话,取决于实现。它也不需要在所有方面都是最快的。