我正在寻找关于基本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++解决方案感兴趣,我使用模板和仅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;

}

其他回答

如果你需要固定大小的类型,使用类型像uint32_t(32位无符号整数)定义在stdint.h。它们在C99中指定。

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

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

在64位机器上:

int: 4
long: 8
long long: 8
void*: 8
size_t: 8

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

char的另一个限制是它的大小总是1字节,或CHAR_BIT位(因此得名)。这在标准中有明确的说明。

C标准是c++标准的规范参考,所以即使它没有明确地说明这些要求,c++也要求C标准所要求的最小范围(第22页),这与MSDN上的数据类型范围相同:

signed char: -127 to 127 (note, not -128 to 127; this accommodates 1's-complement and sign-and-magnitude platforms) unsigned char: 0 to 255 "plain" char: same range as signed char or unsigned char, implementation-defined 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

c++(或C)实现可以用bytes sizeof(type)定义类型的大小为任何值,只要

表达式sizeof(type) * CHAR_BIT计算为足够高的位数,以包含所需的范围,并且 类型的顺序仍然有效(例如sizeof(int) <= sizeof(long))。

综上所述,我们可以保证:

Char,有符号Char和无符号Char至少是8位 有符号short、无符号short、有符号int和无符号int至少是16位 有符号长和无符号长至少是32位 有符号long long和无符号long long至少是64位

对于float或double类型的大小没有任何保证,除非double类型提供的精度至少与float类型相同。

实际的特定于实现的范围可以在C中的<limits.h>头文件中找到,或者在c++中的<climits>头文件中找到(或者更好的是,在<limits>头文件中找到模板化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();

我注意到这里所有的其他答案几乎都集中在整型上,而提问者也问了浮点数。

我不认为c++标准需要它,但是现在大多数常见平台的编译器通常都遵循IEEE754标准的浮点数。该标准指定了四种类型的二进制浮点数(以及一些BCD格式,我从未见过c++编译器支持这些格式):

半精度(binary16) - 11位有效值,指数范围-14到15 单精度(binary32) - 24位有效值,指数范围-126至127 双精度(binary64) - 53位有效值,指数范围-1022到1023 四倍精度(binary128) - 113位有效值,指数范围-16382到16383

那么,这是如何映射到c++类型的呢?一般浮子采用单精度;因此,sizeof(float) = 4。然后double使用双精度(我相信这是double名称的来源),长double可能是双精度或四倍精度(在我的系统上是四倍精度,但在32位系统上可能是双精度)。我不知道有哪个编译器能提供半精度浮点数。

总结一下,通常是这样的:

Sizeof (float) = 4 Sizeof (double) = 8 Sizeof (long double) = 8或16