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 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
Tentei encontrar, sem muito sucesso, informações confiáveis indicando os tamanhos de char
, short
, int
, long
, double
, float
(e outros tipos eu não pensar) sob diferentes arquiteturas e compiladores.
int16_t
,int32_t
eint64_t
(é necessário oiostream
incluem, por que, se bem me lembro). O que é interessante sobre isso é que o int64_t não deve ter problemas em um sistema de 32 bits (isso afetará o desempenho).<cstdint>
, não<iostream>
.Respostas:
O padrão C ++ não especifica o tamanho dos tipos integrais em bytes, mas especifica os intervalos mínimos que eles devem poder manter. Você pode inferir o tamanho mínimo em bits do intervalo necessário. Você pode inferir o tamanho mínimo em bytes disso e o valor da
CHAR_BIT
macro que define o número de bits em um byte . Em todas as plataformas, exceto as mais obscuras, é 8 e não pode ser inferior a 8. Isso porque deve ser grande o suficiente para conter "as unidades de código de oito bits do formulário de codificação Unicode UTF-8".Uma restrição adicional
char
é que seu tamanho é sempre 1 byte ouCHAR_BIT
bits (daí o nome). Isto é afirmado explicitamente no padrão.O padrão C é uma referência normativa para o padrão C ++, portanto, mesmo que não indique esses requisitos explicitamente, o C ++ exige os intervalos mínimos exigidos pelo padrão C (página 22), que são os mesmos que os do Tipo de dados no MSDN :
signed char
: -127 a 127 (observe, não -128 a 127; isso acomoda plataformas de complemento de 1 e sinal e magnitude)unsigned char
: 0 a 255char
: mesmo intervalo quesigned char
ouunsigned char
, definido pela implementaçãosigned short
: -32767 a 32767unsigned short
: 0 a 65535signed int
: -32767 a 32767unsigned int
: 0 a 65535signed long
: -2147483647 a 2147483647unsigned long
: 0 a 4294967295signed long long
: -9223372036854775807 a 9223372036854775807unsigned long long
: 0 a 18446744073709551615Uma implementação C ++ (ou C) pode definir o tamanho de um tipo em bytes
sizeof(type)
para qualquer valor, desde quesizeof(type) * CHAR_BIT
avaliada para um número de bits alto o suficiente para conter os intervalos necessários esizeof(int) <= sizeof(long)
).Juntando tudo isso, temos a garantia de que:
char
,,signed char
eunsigned char
são pelo menos 8 bitssigned short
,unsigned short
,signed int
, Eunsigned int
são pelo menos 16 bitssigned long
eunsigned long
tem pelo menos 32 bitssigned long long
eunsigned long long
tem pelo menos 64 bitsNenhuma garantia é feita sobre o tamanho
float
ou adouble
exceção quedouble
fornece pelo menos a mesma precisão quefloat
.Os intervalos reais específicos da implementação podem ser encontrados no
<limits.h>
cabeçalho em C ou<climits>
em C ++ (ou, melhor ainda,std::numeric_limits
em modelos no<limits>
cabeçalho).Por exemplo, é assim que você encontrará o alcance máximo para
int
:C:
C ++ :
fonte
char
", e não o significado usual.Para sistemas de 32 bits, o padrão 'de facto' é ILP32 - ou seja,
int
,long
e ponteiro são todas as quantidades de 32 bits.Para sistemas de 64 bits, o principal padrão de fato do Unix é o LP64 -
long
e o ponteiro é de 64 bits (masint
é de 32 bits). O padrão de 64-bit Windows é LLP64 -long long
e ponteiro são de 64 bits (maslong
eint
são ambas 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
, apesar do teste no script de configuração do Perl.Observe que havia máquinas (Crays)
CHAR_BIT
muito maiores que 8. Isso significava, IIRC, quesizeof(int)
também era 1, porque amboschar
eint
eram de 32 bits.fonte
[u]int32_t
ou similar, se quiser usar 64 bits[u]int64_t
... se não tiver um cabeçalho para eles, faça o download ou crie um, de preferência com a seleção do tempo de compilação de tipos ou asserções estáticas para verificar o tamanho. pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html Se os tamanhos precisos não são tão importantes e você se importa apenas com o tamanho, é aconselhável seguir as plataformas modernas de PC / servidor.int get_char(FILE *fp, char *c)
que retorna EOF ou 0 e define*c
.uint32_t x=1,y=2;
o valor de,x-y
deva ser 4294967295 em plataformas onde "int" seja 32 bits ou menor, e -1 em plataformas em que "int" seja 33 bits ou maior. Além disso, requer quex*y
seja avaliado usando aritmética modular para todos os valores de x e y se "int" for 32 bits ou menor e aritmética convencional se 65 bits ou maior, mas não impõe nenhum requisito sobre o que pode acontecer com valores grandes de x e y se "int" for de 33 a 64 bits.Na prática, não existe tal coisa. Freqüentemente, você pode esperar
std::size_t
representar o tamanho inteiro nativo não assinado na arquitetura atual. ou seja, 16 bits, 32 bits ou 64 bits, mas nem sempre é o caso, conforme indicado nos comentários a esta resposta.No que diz respeito a todos os outros tipos internos, isso realmente depende do compilador. Aqui estão dois trechos retirados do rascunho atual do último padrão C ++:
Se você quiser, pode estaticamente (em tempo de compilação) afirmar o tamanho desses tipos fundamentais. Ele alertará as pessoas a pensar em portar seu código se o tamanho das suposições mudar.
fonte
Existe padrão.
O padrão C90 exige que
O padrão C99 exige que
Aqui estão as especificações do C99 . A página 22 detalha tamanhos de diferentes tipos integrais.
Aqui estão os tamanhos do tipo int (bits) para plataformas Windows:
Se você está preocupado com a portabilidade ou deseja que o nome do tipo reflita o tamanho, consulte o cabeçalho
<inttypes.h>
, onde estão disponíveis as seguintes macros:int8_t
tem 8 bits eint16_t
16 bits, etc.fonte
sizeof(long) < sizeof(long long)
em oposição ao simétricosizeof(long) <= sizeof(long long)
?Se você precisar de tipos de tamanho fixo, use tipos como uint32_t (número inteiro não assinado de 32 bits) definido em stdint.h . Eles são especificados em C99 .
fonte
CHAR_BIT == 16
, por exemplo, não possuiint8_t
. Qualquer plataforma que não use o complemento de dois não terá nenhum deles (como o complemento de dois é exigido pelo padrão).Atualizado: o C ++ 11 trouxe os tipos do TR1 oficialmente para o padrão:
E os tipos "dimensionados" de
<cstdint>
Além disso, você obtém:
Esses tipos representam os menores números 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:
O que significa "rápido", se é que existe alguma coisa, depende da implementação. Também não precisa ser o mais rápido para todos os fins.
fonte
O padrão C ++ diz assim:
3.9.1, §2:
A conclusão: depende de qual arquitetura você está trabalhando. Qualquer outra suposição é falsa.
fonte
Não, não há padrão para tamanhos de tipo. O padrão exige apenas que:
A melhor coisa que você pode fazer se desejar variáveis de tamanhos fixos é usar macros como esta:
Então você pode usar WORD para definir suas variáveis. Não é que eu goste disso, mas é a maneira mais portátil .
fonte
#include <boost/cstdint.hpp>
Temos permissão para definir um sinônimo para o tipo para que possamos criar nosso próprio "padrão".
Em uma máquina na qual sizeof (int) == 4, podemos definir:
Portanto, quando transferimos o código para uma máquina diferente, na qual o tamanho de int longo é 4, podemos redefinir a ocorrência única de int.
fonte
<stdint.h>
(C99 e posterior, e o padrão C ++ adotado na versão C99 da biblioteca C).Para números de ponto flutuante, existe um padrão (IEEE754) : flutuadores são 32 bits e duplos são 64. Esse é um padrão de hardware, não um padrão C ++, portanto, os compiladores poderiam teoricamente definir float e dobrar para outro tamanho, mas na prática eu ' nunca vi uma arquitetura que usasse algo diferente.
fonte
double
tem o mesmo tamanhofloat
(eint
o mesmo quechar
, ambos são 16 bits). Mas eles têm 64 bitslong double
.Existe um padrão e ele é especificado nos vários documentos de padrões (ISO, ANSI e outros enfeites).
A Wikipedia possui uma ótima página que explica os vários tipos e o máximo que eles podem armazenar: Inteiro em Ciência da Computação.
No entanto, mesmo com um compilador C ++ padrão, você pode descobrir com relativa facilidade usando o seguinte snippet de código:
A documentação para std :: numeric_limits pode ser encontrada em Roguewave . Inclui uma infinidade de outros comandos que você pode chamar para descobrir os vários limites. Isso pode ser usado com qualquer tipo arbitrário que transmita tamanho, por exemplo std :: streamsize.
A resposta de João contém a melhor descrição, pois essas são garantidas. Não importa em que plataforma você está, há outra página boa que entra em mais detalhes sobre quantos bits cada tipo DEVE conter: tipos int , que são definidos no padrão.
Eu espero que isso ajude!
fonte
1) Tabela N1 no artigo " Os problemas esquecidos do desenvolvimento de programas de 64 bits "
2) " Modelo de dados "
fonte
Você pode usar:
datatype = int
,long int
etc. Você poderá ver o tamanho do tipo de dados digitado.fonte
Quando se trata de tipos integrados para diferentes arquiteturas e diferentes compiladores, basta executar o código a seguir na sua arquitetura com o seu compilador para ver o que ele gera. Abaixo mostra o meu Ubuntu 13.04 saída do (Raring Ringtail) de 64 bits g ++ 4.7.3. Observe também o que foi respondido abaixo e é por isso que a saída é ordenada como tal:
"Existem cinco tipos de números inteiros assinados padrão: char assinado, int curto, int, longo int e longo longo int. Nesta lista, cada tipo fornece pelo menos tanto armazenamento quanto os que o precedem na lista."
fonte
sizeof(char)
não deve ser incluído.Como mencionado, o tamanho deve refletir a arquitetura atual. Você pode dar uma olhada
limits.h
se quiser ver como o seu compilador atual está lidando com as coisas.fonte
Como outros já responderam, todos os "padrões" deixam a maioria dos detalhes como "implementação definida" e afirmam apenas que o tipo "char" possui uma largura mínima de "char_bis" e que "char <= short <= int <= long < = long long "(float e double são praticamente consistentes com os padrões de ponto flutuante IEEE, e long double é tipicamente igual a double - mas pode ser maior nas implementações mais atuais).
Parte das razões para não ter valores muito específicos e exatos é que 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 da palavra "char" pode ser de 4 bits ou 7 bits, ou até mesmo algum valor diferente dos computadores "8 / 16- / 32- / 64-bits" aos quais o usuário comum de computador doméstico está exposto. (O tamanho da palavra 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 ame, mas para plataformas diferentes. Alguns padrões e práticas (especialmente limits.he semelhantes) são comuns o suficiente para que a maioria dos compiladores tenha suporte para determinar o tipo mais adequado para um intervalo específico de valores, mas não o número de bits usados. (Ou seja, se você sabe que precisa manter valores entre 0 e 127, pode determinar que seu compilador suporta um tipo "int8" de 8 bits, que será grande o suficiente para manter toda a faixa desejada, mas não algo como um tipo "int7", que seria uma correspondência exata para 7 bits.)
Nota: Muitos pacotes de código-fonte Un * x usavam o script "./configure" que analisará os recursos do compilador / sistema e produzirá um Makefile e config.h adequados. Você pode examinar alguns desses scripts para ver como eles funcionam e como eles examinam os recursos do sistema / compilador e seguem sua liderança.
fonte
Se você estiver interessado em uma solução C ++ pura, usei modelos e apenas o código padrão C ++ para definir tipos em tempo de compilação, com base no tamanho dos bits. Isso torna a solução portátil entre 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 verifique a lista e, usando o modelo numeric_limits, selecione o tipo com o tamanho especificado.
Incluindo esse cabeçalho, você tem 8 tipos 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 É DADO SEM GARANTIA, VERIFIQUE DUPLO.
Eu também sou novo na METAPROGRAMMING, sinta-se livre para editar e corrigir este código.
Testado com DevC ++ (portanto, uma versão do gcc em torno de 3.5)
fonte
onde
X
está umchar
,int
,long
etc .. lhe dará o tamanho deX
em bits.fonte
sizeof(type)*CHAR_BIT
retémCHAR_BIT
fosse garantido ter 8 bits,<< 3
é apenas uma maneira ofuscada de escrever* 8
ou* CHAR_BIT
.De Alex B O padrão C ++ não especifica o tamanho dos tipos integrais em bytes, mas especifica os intervalos mínimos que eles devem poder manter. Você pode inferir o tamanho mínimo em bits do intervalo necessário. Você pode deduzir o tamanho mínimo em bytes disso e o valor da macro CHAR_BIT que define o número de bits em um byte (em todas as plataformas, exceto as mais obscuras, é 8 e não pode ser inferior a 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 (observe, não -128 a 127; isso acomoda plataformas de complemento de 1) caractere não assinado: 0 a 255 caractere "comum": -127 a 127 ou 0 a 255 (depende do sinal de char padrão) assinado curto: -32767 a 32767 sem sinal abreviado: 0 a 65535 assinado int: -32767 a 32767 int sem sinal assinado: 0 a 65535 assinado longo: -2147483647 a 2147483647 sem sinal longo: 0 a 4294967295 longo assinado: -9223372036854775807 a 922337203685 longo long: 0 a 18446744073709551615 Uma implementação C ++ (ou C) pode definir o tamanho de um tipo em bytes sizeof (type) para qualquer valor, desde que
a expressão sizeof (type) * CHAR_BIT avalia o número de bits suficiente para conter os intervalos necessários e a ordem do tipo ainda é válida (por exemplo, sizeof (int) <= sizeof (long)). Os intervalos específicos da implementação reais podem ser encontrados no cabeçalho em C ou em C ++ (ou melhor ainda, std :: numeric_limits no cabeçalho).
Por exemplo, é assim que você encontrará o alcance máximo para int:
C:
C ++:
Isso está correto, no entanto, você também estava certo ao dizer que: char: 1 byte curto: 2 bytes int: 4 bytes de comprimento: 4 bytes flutuante: 4 bytes duplo: 8 bytes
Como as arquiteturas de 32 bits ainda são as padrão e as mais usadas, elas mantêm esses tamanhos padrão desde os dias anteriores a 32 bits, quando a memória estava menos disponível, e para compatibilidade e padronização anteriores, ela permaneceu a mesma. Mesmo sistemas de 64 bits tendem a usá-los e têm extensões / modificações. Consulte isso para obter mais informações:
http://en.cppreference.com/w/cpp/language/types
fonte
Percebo que todas as outras respostas aqui se concentraram quase exclusivamente em tipos integrais, enquanto o questionador também perguntou sobre pontos flutuantes.
Não acho que o padrão C ++ exija, mas os compiladores para as plataformas mais comuns hoje em dia geralmente seguem o padrão IEEE754 para seus números de ponto flutuante. Esse padrão especifica quatro tipos de ponto flutuante binário (além de alguns formatos BCD, aos quais nunca vi suporte nos compiladores C ++):
Como isso é mapeado para os tipos C ++? Geralmente os
float
usos precisão única; assimsizeof(float) = 4
,. Em seguida,double
usa precisão dupla (acredito que essa é a fonte do nomedouble
) elong double
pode ser precisão dupla ou quádrupla (é quádrupla no meu sistema, mas em sistemas de 32 bits pode ser dupla). Não conheço nenhum compilador que ofereça pontos flutuantes de meia precisão.Em resumo, este é o habitual:
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8 ou 16fonte
Como você mencionou - depende muito do compilador e da plataforma. Para isso, verifique o padrão ANSI, http://home.att.net/~jackklein/c/inttypes.html
Aqui está o exemplo para o compilador da Microsoft: Data Type Ranges .
fonte
Você pode usar variáveis fornecidas por bibliotecas como OpenGL , Qt , etc.
Por exemplo, o Qt fornece qint8 (com garantia de 8 bits em todas as plataformas suportadas pelo Qt), qint16, qint32, qint64, quint8, quint16, quint16, quint32, quint64, etc.
fonte
Em uma máquina de 64 bits:
fonte
int
são 8 bytes, mas a outra não é garantida. Não há nada que diga quechar
deve ter apenas 8 bits. É permitido tersizeof(void*)==4
64 bits.Existem quatro tipos de números inteiros com base no tamanho:
fonte
short
,int
elong
todos os inteiros de 32 bits.int
, não a palavra "número inteiro".