Diferença entre int32, int, int32_t, int8 e int8_t

103

Me deparei com o tipo de dados int32_tem um programa C recentemente. Eu sei que ele armazena 32 bits, mas não armazena inte int32faz o mesmo?

Além disso, desejo usar charem um programa. Posso usar no int8_tlugar? Qual é a diferença?

Para resumir: qual é a diferença entre int32, int, int32_t, int8 e int8_t em C?

linuxfreak
fonte

Respostas:

122

Entre int32e int32_t, (e da mesma forma entre int8e int8_t) a diferença é bastante simples: o padrão C define int8_te int32_t, mas não define nada com o nome int8ou int32- o último (se existirem) é provavelmente de algum outro cabeçalho ou biblioteca (muito provavelmente é anterior à adição de int8_te int32_tem C99).

Plain inté um pouco diferente dos outros. Onde int8_te int32_tcada um tem um tamanho especificado, intpode ser qualquer tamanho> = 16 bits. Em momentos diferentes, 16 bits e 32 bits foram razoavelmente comuns (e para uma implementação de 64 bits, provavelmente deveria ser 64 bits).

Por outro lado, inttem a garantia de estar presente em todas as implementações de C, onde int8_te int32_tnão estão. É provável que haja dúvidas se isso é importante para você. Se você usa C em pequenos sistemas embarcados e / ou compiladores mais antigos, pode ser um problema. Se você usá-lo principalmente com um compilador moderno em máquinas desktop / servidor, provavelmente não será.

Oops - perdi a parte sobre char. Você usaria ao int8_tinvés de char se (e somente se) você quisesse um tipo inteiro garantido com exatamente 8 bits de tamanho. Se você deseja armazenar caracteres, provavelmente deseja usar em seu charlugar. Seu tamanho pode variar (em termos de número de bits), mas é garantido que seja exatamente um byte. Porém, uma pequena estranheza: não há garantia sobre se um plano charé assinado ou não (e muitos compiladores podem torná-lo qualquer um, dependendo de um sinalizador de tempo de compilação). Se você precisa garantir que ele seja assinado ou não, você precisa especificar isso explicitamente.

Jerry Coffin
fonte
1
@linuxfreak: Não tenho certeza bool_t- nunca ouvi falar disso antes. O padrão C é definido _Boolcomo um tipo integrado. boolé definido apenas se você #include <stdbool.h>(como uma macro que se expande para _Bool).
Jerry Coffin
5
Você disse "para uma implementação de 64 bits, (int) provavelmente deve ser de 64 bits". Na prática, int é de 32 bits em todas as plataformas comuns de 64 bits, incluindo Windows, Mac OS X, Linux e vários tipos de UNIX. Uma exceção é o Cray / UNICOS, mas eles estão fora de moda atualmente.
Sam Watkins
6
@SamWatkins: Sim, é por isso que disse cuidadosamente "deveria ser", não "é". O padrão diz que é "o tamanho natural sugerido pela arquitetura", o que (IMO) significa em um processador de 64 bits, ele realmente deve ser de 64 bits (embora, para o bem ou para o mal, você está certo de que geralmente não é t). De um ponto de vista mais prático, é extremamente útil ter um tipo de 32 bits entre os tipos em C89, e se int for 64 bits, long deve ter pelo menos 64 bits também, então muitas vezes não haveria 32 bits tipo.
Jerry Coffin
2
@barlop: Sim. (C e C ++ exigem um intervalo mínimo de 255 valores para char, portanto, requer pelo menos 8 bits, mas pode ser mais).
Jerry Coffin
2
Eu sempre tive a impressão de que um byte era exatamente 8 bits, não em qualquer lugar de 8 bits para cima
ErlVolton
18

Os tipos de dados _t são tipos de typedef no cabeçalho stdint.h, enquanto int é um tipo de dados fundamental integrado. Isso torna o _t disponível apenas se stdint.h existir. int por outro lado tem a garantia de existência.

Super homen
fonte
1
Por que alguém usaria os _t?
Deven
@Deven Para evitar o caso em que seu código funciona em algum lugar, mas não em outro lugar.
Franklin Yu
2

Sempre tenha em mente que 'tamanho' é variável se não for especificado explicitamente, portanto, se você declarar

 int i = 10;

Em alguns sistemas, pode resultar em inteiros de 16 bits por compilador e em outros pode resultar em inteiros de 32 bits (ou inteiros de 64 bits em sistemas mais novos).

Em ambientes embarcados, isso pode resultar em resultados estranhos (especialmente ao lidar com E / S mapeada na memória ou pode ser considerada uma situação de array simples), por isso é altamente recomendado especificar variáveis ​​de tamanho fixo. Em sistemas legados, você pode encontrar

 typedef short INT16;
 typedef int INT32;
 typedef long INT64; 

A partir do C99, os designers adicionaram o arquivo de cabeçalho stdint.h que essencialmente aproveita typedefs semelhantes.

Em um sistema baseado em Windows, você pode ver entradas no arquivo de cabeçalho stdin.h como

 typedef signed char       int8_t;
 typedef signed short      int16_t;
 typedef signed int        int32_t;
 typedef unsigned char     uint8_t;

Há muito mais nisso, como inteiros de largura mínima ou tipos inteiros de largura exata, acho que não é uma coisa ruim explorar stdint.h para um melhor entendimento.

Naumann
fonte
1
Seu código contém um erro de digitação: typedef short INT16;não typedefs short INT16.
Galaxy