c++ - primitivos - int long unsigned




O que o padrão C++ declara o tamanho de int, long type to be? (16)

Eu estou procurando informações detalhadas sobre o tamanho dos tipos básicos de C ++. Eu sei que isso depende da arquitetura (16 bits, 32 bits, 64 bits) e do compilador.

Mas existem padrões para o C ++?

Estou usando o Visual Studio 2008 em uma arquitetura de 32 bits. Aqui está o que eu recebo:

char  : 1 byte
short : 2 bytes
int   : 4 bytes
long  : 4 bytes
float : 4 bytes
double: 8 bytes

Eu tentei encontrar, sem muito sucesso, informações confiáveis ​​indicando os tamanhos de char , short , int , long , double , float (e outros tipos que eu não pensei) sob diferentes arquiteturas e compiladores.



Atualizado: C ++ 11 trouxe os tipos de TR1 oficialmente para o padrão:

  • long long int
  • sem assinatura longa longa int

E os tipos "dimensionados" de <cstdint>

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (e as contrapartes não assinadas).

Além disso, você recebe:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • Além disso, as contrapartes não assinadas.

Esses tipos representam os menores tipos inteiros com pelo menos o número especificado de bits. Da mesma forma, existem os tipos inteiros "mais rápidos" com pelo menos o número especificado de bits:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • Além disso, as versões não assinadas.

O que "rápido" significa, se alguma coisa, depende da implementação. Não precisa ser o mais rápido para todos os propósitos.


Como outros já responderam, os "padrões" todos deixam a maioria dos detalhes como "implementação definida" e apenas afirmam que o tipo "char" está em "char_bis", e que "char <= short <= int <= long < = long long "(float e double são bastante consistentes com os padrões de ponto flutuante IEEE, e long double é tipicamente igual a double - mas pode ser maior em implementações mais atuais).

Parte das razões para não ter valores muito específicos e exatos é porque linguagens como C / C ++ foram projetadas para serem portáveis ​​para um grande número de plataformas de hardware - Incluindo sistemas de computador nos quais o tamanho de palavra "char" pode ser de 4 bits ou 7 bits, ou mesmo algum valor diferente dos computadores "8- / 16- / 32- / 64-bit" aos quais o usuário médio do computador doméstico está exposto. (Tamanho do Word aqui significa quantos bits de largura o sistema normalmente opera - Novamente, nem sempre são 8 bits como os usuários de computadores domésticos podem esperar.)

Se você realmente precisa de um objeto (no sentido de uma série de bits representando um valor integral) de um número específico de bits, a maioria dos compiladores possui algum método para especificar isso; Mas geralmente não é portátil, mesmo entre compiladores feitos pela empresa, mas para diferentes plataformas. Alguns padrões e práticas (especialmente limits.h e similares) são comuns o suficiente para que a maioria dos compiladores tenha suporte para determinar o tipo de melhor ajuste para um intervalo específico de valores, mas não o número de bits usados. (Isto é, se você sabe que precisa manter valores entre 0 e 127, você pode determinar que seu compilador suporta um tipo "int8" de 8 bits que será grande o suficiente para manter o intervalo completo desejado, mas não algo como um "int7" tipo que seria uma correspondência exata para 7 bits.)

Nota: Muitos pacotes fonte Un * x usaram o script "./configure", que testará as capacidades do compilador / sistema e produzirá um Makefile e um config.h adequados. Você pode examinar alguns desses scripts para ver como eles funcionam e como eles examinam os recursos do comutador / sistema e seguem sua liderança.


De Alex B O padrão C ++ não especifica o tamanho dos tipos integrais em bytes, mas especifica intervalos mínimos que eles devem ser capazes de manter. Você pode inferir o tamanho mínimo em bits do intervalo necessário. Você pode inferir o tamanho mínimo em bytes daquele e o valor da macro CHAR_BIT que define o número de bits em um byte (em todas as plataformas menos obscuras é 8, e não pode ser menor que 8).

Uma restrição adicional para char é que seu tamanho é sempre 1 byte, ou bits CHAR_BIT (daí o nome).

Os intervalos mínimos exigidos pelo padrão (página 22) são:

e tipos de dados no MSDN:

caractere assinado: -127 a 127 (observação, não -128 a 127; isso acomoda plataformas complemento de 1) char não assinado: 0 a 255 "simples" char: -127 a 127 ou 0 a 255 (depende da assinatura de caractere padrão) assinado curto: -32767 a 32767 breve sem assinatura: 0 a 65535 assinado int: -32767 a 32767 sem assinatura int: 0 a 65535 assinado: -2147483647 a 2147483647 longo sem assinatura: 0 a 4294967295 assinado longo: -9223372036854775807 a 9223372036854775807 sem assinatura longo: 0 a 18446744073709551615 Uma implementação em C ++ (ou C) pode definir o tamanho de um tipo em bytes sizeof (tipo) para qualquer valor, desde que

a expressão sizeof (type) * CHAR_BIT avalia o número de bits o suficiente para conter os intervalos requeridos, e a ordenação do tipo ainda é válida (por exemplo, sizeof (int) <= sizeof (long)). Os intervalos específicos de implementação reais podem ser encontrados no cabeçalho em C ou em C ++ (ou ainda melhor, std :: numeric_limits no cabeçalho).

Por exemplo, é assim que você encontrará o alcance máximo para 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();

Isso está correto, no entanto, você também estava certo em dizer que: char: 1 byte short: 2 bytes int: 4 bytes: 4 bytes float: 4 bytes double: 8 bytes

Como as arquiteturas de 32 bits ainda são o padrão e as mais usadas, elas mantiveram esses tamanhos padrão desde os dias anteriores a 32 bits, quando a memória estava menos disponível e, para compatibilidade com versões anteriores e padronização, permaneceu a mesma coisa. Mesmo os sistemas de 64 bits tendem a usá-los e possuem extensões / modificações. Por favor, referencie isto para mais informações:

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


Não é padrão.

A norma C90 exige que

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

O padrão C99 exige que

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

Aqui estão as especificações C99 . Página 22 detalhes tamanhos de diferentes tipos integrais.

Aqui estão os tamanhos de tipo int (bits) para plataformas Windows:

Type           C99 Minimum     Windows 32bit
char           8               8
short          16              16
int            16              32
long           32              32
long long      64              64

Se você estiver preocupado com a portabilidade, ou se quiser que o nome do tipo reflita o tamanho, você pode ver o cabeçalho <inttypes.h> , onde as seguintes macros estão disponíveis:

int8_t
int16_t
int32_t
int64_t

int8_t é garantido como 8 bits, e int16_t tem garantia de 16 bits, etc.


Não, não há padrão para tamanhos de tipo. Padrão requer apenas que:

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

A melhor coisa que você pode fazer se quiser variáveis ​​de tamanhos fixos é usar macros como esta:

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

Então você pode usar o WORD para definir suas variáveis. Não é que eu goste disso, mas é a maneira mais portátil .


O C ++ Standard diz assim:

3.9.1, §2:

Existem cinco tipos inteiros assinados: "char assinado", "short int", "int", "long int" e "long long int". Nessa lista, cada tipo fornece pelo menos o máximo de armazenamento que os precedentes na lista. Os planetas têm o tamanho natural sugerido pela arquitetura do ambiente de execução (44); os outros tipos inteiros assinados são fornecidos para atender necessidades especiais.

(44) ou seja, grande o suficiente para conter qualquer valor no intervalo de INT_MIN e INT_MAX, conforme definido no cabeçalho <climits> .

A conclusão: depende de qual arquitetura você está trabalhando. Qualquer outra suposição é falsa.


O padrão C ++ não especifica o tamanho dos tipos integrais em bytes, mas especifica intervalos mínimos que eles devem ser capazes de manter. Você pode inferir o tamanho mínimo em bits do intervalo necessário. Você pode inferir o tamanho mínimo em bytes daquele e o valor da macro CHAR_BIT que define o número de bits em um byte (em todas as plataformas menos obscuras é 8, e não pode ser menor que 8).

Uma restrição adicional para char é que seu tamanho é sempre 1 byte, ou bits CHAR_BIT (daí o nome).

Os intervalos mínimos exigidos pelo padrão (página 22) são:

e tipos de dados no MSDN :

  1. signed char : -127 a 127 (observação, não -128 a 127; isso acomoda plataformas de complemento e sinal de magnitude 1)
  2. unsigned char : 0 a 255
  3. "simples" char : mesmo intervalo como signed char ou unsigned char , implementation-defined
  4. signed short : -32767 a 32767
  5. unsigned short : 0 a 65535
  6. signed int : -32767 a 32767
  7. unsigned int : 0 a 65535
  8. signed long : -2147483647 a 2147483647
  9. unsigned long : 0 a 4294967295
  10. signed long long : -9223372036854775807 a 9223372036854775807
  11. unsigned long long : 0 a 18446744073709551615

Uma implementação de C ++ (ou C) pode definir o tamanho de um tipo em bytes sizeof(type) para qualquer valor, desde que

  1. a expressão sizeof(type) * CHAR_BIT avaliada como um número de bits alto o suficiente para conter os intervalos requeridos, e
  2. a ordenação do tipo ainda é válida (por exemplo, sizeof(int) <= sizeof(long) ).

Os intervalos específicos da implementação reais podem ser encontrados em <limits.h> cabeçalho em C, ou <climits> em C ++ (ou, melhor ainda, std::numeric_limits no cabeçalho <limits> ).

Por exemplo, é assim que você encontrará o alcance máximo para 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();

Para sistemas de 32 bits, o padrão 'de fato' é o ILP32 - isto é, int , long e o ponteiro são todos de 32 bits.

Para sistemas de 64 bits, o padrão principal de 'Unix' de fato é LP64 e o ponteiro é de 64 bits (mas int é de 32 bits). O padrão do Windows de 64 bits é o LLP64 - long long e o ponteiro são de 64 bits (mas o long e o int são de 32 bits).

Ao mesmo tempo, alguns sistemas Unix usavam uma organização ILP64.

Nenhum desses padrões de fato é legislado pelo padrão C (ISO / IEC 9899: 1999), mas todos são permitidos por ele.

E, por definição, sizeof(char) é 1 , não obstante o teste no script de configuração do Perl.

Note que havia máquinas (Crays) onde CHAR_BIT era muito maior que 8. Isso significava, IIRC, que sizeof(int) também era 1, porque char e int eram 32-bit.


Percebo que todas as outras respostas aqui se concentraram quase exclusivamente em tipos integrais, enquanto o questionador também perguntou sobre pontos flutuantes.

Eu não acho que o padrão C ++ exija, mas compiladores para as plataformas mais comuns atualmente seguem o padrão IEEE754 para seus números de ponto flutuante. Esse padrão especifica quatro tipos de ponto flutuante binário (bem como alguns formatos BCD, aos quais eu nunca vi suporte em compiladores C ++):

  • Half precision (binary16) - significando de 11 bits, faixa de expoente -14 a 15
  • Precisão simples (binary32) - significando de 24 bits, faixa de expoente -126 a 127
  • Precisão dupla (binary64) - significand de 53 bits, faixa expoente de -1022 a 1023
  • Precisão quádrupla (binary128) - significand de 113 bits, faixa de expoente -16382 a 16383

Como isso mapeia para os tipos C ++, então? Geralmente, os floatusos de precisão única; assim, sizeof(float) = 4. Em seguida, doubleusa precisão dupla (acredito que é a origem do nome double) e long doublepode ser precisão dupla ou quádrupla (é quádruplo no meu sistema, mas em sistemas de 32 bits pode ser duplo). Eu não conheço nenhum compilador que ofereça pontos flutuantes de meia precisão.

Em resumo, isso é o usual:

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8 ou 16

Se você estiver interessado em uma solução C ++ pura, fiz uso de modelos e apenas código padrão C ++ para definir tipos em tempo de compilação com base em seu tamanho de bit. Isso torna a solução portátil em todos os compiladores.

A idéia por trás é muito simples: Crie uma lista contendo os tipos char, int, short, long, long long (versões assinadas e não assinadas) e faça a varredura da lista e pelo uso do template numeric_limits selecione o tipo com o tamanho dado.

Incluindo este cabeçalho você tem 8 tipo stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64.

Se algum tipo não puder ser representado, ele será avaliado como stdtype :: null_type também declarado nesse cabeçalho.

O CÓDIGO ABAIXO É FORNECIDO SEM GARANTIA, POR FAVOR, VERIFIQUE-O DUAS.
Eu sou novo em METAPROGRAMMING também, sentir-se livre para editar e corrigir este código.
Testado com DevC ++ (assim, uma versão do gcc em torno de 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;

}

Se você precisar de tipos de tamanho fixos, use tipos como uint32_t (inteiro sem sinal de 32 bits) definido em stdint.h . Eles são especificados em C99 .


Você pode usar:

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

datatype = int , long int etc. Você poderá ver o tamanho para qualquer tipo de dado que digitar.


Em uma máquina de 64 bits:

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


Você pode usar variáveis ​​fornecidas por bibliotecas como OpenGL , Qt , etc.

Por exemplo, o Qt provides qint8 (garantido para ser de 8 bits em todas as plataformas suportadas pelo Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.







c++-faq