Tamanho de int em C em arquiteturas diferentes
-
05-07-2019 - |
Pergunta
Estou ciente de que a especificação da linguagem C não dita o tamanho exato de cada tipo inteiro (por exemplo, int
).
O que eu estou querendo saber é: Existe uma maneira em C (não C ++) para definir um tipo inteiro com um tamanho específico que garante que vai ser o mesmo em diferentes arquiteturas? Como:
typedef int8 <an integer with 8 bits>
typedef int16 <an integer with 16 bits>
Ou qualquer outra forma que permita que outras partes do programa a ser compilado em uma arquitetura diferente.
Solução
O que você quer é <stdint.h>
, que compiladores que estejam em conformidade com o padrão C ( "C99") irá implementar. Infelizmente, isso não inclui Microsoft. Felizmente, um projeto de código aberto oferece uma <stdint.h>
para Windows, consulte msinttypes .
Isto irá permitir que você use int32_t
e uint32_t
, mais 8, 16 e 64, e muitos outros.
Nota: o arquivo de cabeçalho em si não é opcional no padrão, no entanto, a maioria dos tipos de cabeçalho são individualmente opcional. Alguns não são. Os tipos mais comumente utilizados são os opcionais, mas nada impede de usar os necessários. A coisa é, se uma aplicação fornece o cabeçalho em tudo, na prática, definir todos os tipos.
Outras dicas
C99, em stdint.h , define tipos como int8_t
e int16_t
.
Não, o C especifica padrão tamanhos mínimos para tipos integrais, mas não faz nenhuma garantia sobre os tamanhos máximos.
Uma implementação deve fornecer tipos intN_t
se tipos de que o tamanho estão disponíveis. Eu só mencionar que desde que você tinha uma etiqueta multi-plataforma -. uma implementação que não tem um tipo da broca certa largura não precisa fornecer esses tipos
Geralmente você pode selecionar (com configuração define com, por exemplo, cc -D_INT16_IS_INT
e #ifdef
s) o tipo correto de uso para um tamanho pouco específico. Você pode trabalhar os define necessários para cada plataforma que você quer apoio com código C usando CHAR_BIT
e sizeof()
.
A seção relevante do projecto de C1X (n1362) é:
7.18.1.1 tipos inteiros exacta de largura
-
O nome typedef
intN_t
designa um tipo inteiro assinado comN
largura, não padding bits, e representação de um de complemento de dois. Assim,int8_t
denota um tipo inteiro assinado com uma largura de exatamente 8 bits. -
O nome typedef
uintN_t
designa um tipo inteiro não assinado comN
largura. Assim,uint24_t
indica um tipo inteiro sem sinal com uma largura de exactamente 24 bits de. -
Estes tipos são opcionais. No entanto, se uma aplicação fornece inteiro tipos com larguras de 8, 16, 32 ou 64 bits, não há bits de preenchimento, e (para os tipos assinados) que têm representação um de complemento de dois, deve definir o correspondente typedef nomes.
Com relação à seleção de tipos, algo como isto deve ser suficiente:
#ifdef INT32_IS_SHORT
typedef short INT32
#endif
#ifdef INT32_IS_INT
typedef int INT32
#endif
#ifdef INT32_IS_LONG
typedef long INT32
#endif
A menos que você verificar para cada plataforma com #ifdef
ou assim, eu duvido que é facilmente possível. Mas muitas bibliotecas já fazer essa tarefa para você. Para MSVC é __int8
, __int16
, & c. A biblioteca GTK tem semelhante typedefs.
Você pode querer dar uma olhada pstdint.h . É uma implementação portátil do stdint.h, e não requer suporte do compilador C99.
Tanto quanto eu sei, a resposta é não. Nós código para diferentes plataformas e nós apenas usar typedefs para as plataformas específicas usando # if / # outra pessoa. Por exemplo, em Win32: typedef int int32;
Você pode sempre escrever uma biblioteca de aritmética que usou vetores de unsigned char para os números. Dessa forma, você pode usar números de qualquer mordeu comprimento desejado, e até mesmo permitir que o comprimento de bits para variar.
Na verdade, você não precisa implementar uma biblioteca porque GNU MP lida com isso já.