Diferencia entre int32, int, int32_t, int8 e int8_t

103

Me encontré con el tipo de datos int32_ten un programa C recientemente. Sé que almacena 32 bits, pero ¿no lo hace inty int32hace lo mismo?

Además, quiero usarlo charen un programa. ¿Puedo usar int8_ten su lugar? ¿Cuál es la diferencia?

Para resumir: ¿cuál es la diferencia entre int32, int, int32_t, int8 e int8_t en C?

linuxfreak
fuente

Respuestas:

122

Entre int32y int32_t, (y también entre int8y int8_t) la diferencia es bastante simple: el estándar C define int8_ty int32_t, pero no define nada con nombre int8o int32- este último (si es que existe) es probablemente de algún otro encabezado o biblioteca (muy probablemente es anterior a la adición de int8_ty int32_ten C99).

Plain intes bastante diferente a los demás. Donde int8_ty int32_tcada uno tiene un tamaño específico, intpuede ser de cualquier tamaño> = 16 bits. En diferentes momentos, tanto 16 bits como 32 bits han sido razonablemente comunes (y para una implementación de 64 bits, probablemente debería ser de 64 bits).

Por otro lado, intse garantiza que estará presente en cada implementación de C, donde int8_ty int32_tno lo estén. Sin embargo, es probable que se cuestione si esto te importa. Si usa C en pequeños sistemas integrados y / o compiladores más antiguos, puede ser un problema. Si lo usa principalmente con un compilador moderno en máquinas de escritorio / servidor, probablemente no lo será.

Vaya, me perdí la parte sobre char. Usaría en int8_tlugar de char si (y solo si) desea un tipo de entero garantizado para tener exactamente 8 bits de tamaño. Si desea almacenar caracteres, probablemente desee utilizar charen su lugar. Su tamaño puede variar (en términos de número de bits) pero se garantiza que sea exactamente de un byte. Sin embargo, hay una pequeña rareza: no hay garantía de si un plano charestá firmado o sin firmar (y muchos compiladores pueden convertirlo en cualquiera de los dos, dependiendo de un indicador de tiempo de compilación). Si necesita asegurarse de que esté firmado o sin firmar, debe especificarlo explícitamente.

Jerry Coffin
fuente
1
@linuxfreak: No estoy seguro bool_t, nunca había oído hablar de eso antes. El estándar C se define _Boolcomo un tipo integrado. boolse define solo si usted #include <stdbool.h>(como una macro que se expande a _Bool).
Jerry Coffin
5
Dijiste "para una implementación de 64 bits, (int) probablemente debería ser de 64 bits". En la práctica, int es de 32 bits en todas las plataformas comunes de 64 bits, incluidas Windows, Mac OS X, Linux y varias versiones de UNIX. Una excepción es Cray / UNICOS pero están pasados ​​de moda en estos días.
Sam Watkins
6
@SamWatkins: Sí, por eso dije cuidadosamente "debería ser", no "es". El estándar dice que es "el tamaño natural sugerido por la arquitectura", lo que (IMO) significa que en un procesador de 64 bits, realmente debería ser de 64 bits (aunque, para bien o para mal, tienes razón en que generalmente no lo es t). Desde un punto de vista más práctico, es muy útil tener un tipo de 32 bits entre los tipos en C89, y si int es de 64 bits, long también debe ser de al menos 64 bits, por lo que a menudo no habrá 32 bits. tipo.
Jerry Coffin
2
@barlop: Sí. (Tanto C como C ++ exigen un rango mínimo de 255 valores para char, por lo que requiere al menos 8 bits, pero puede ser más).
Jerry Coffin
2
Siempre tuve la impresión de que un byte era exactamente de 8 bits, no de 8 bits en adelante
ErlVolton
18

Los tipos de datos _t son tipos typedef en el encabezado stdint.h, mientras que int es un tipo de datos fundamental integrado. Esto hace que _t esté disponible solo si stdint.h existe. int por otro lado está garantizado para existir.

Superhombre
fuente
1
¿Por qué uno usaría los _t?
Deven
@Deven Para evitar el caso de que su código funcione en algún otro lugar pero no en otro.
Franklin Yu
2

Siempre tenga en cuenta que el 'tamaño' es variable si no se especifica explícitamente, así que si declara

 int i = 10;

En algunos sistemas puede resultar en un entero de 16 bits por compilador y en otros puede resultar en un entero de 32 bits (o entero de 64 bits en sistemas más nuevos).

En entornos embebidos, esto puede dar lugar a resultados extraños (especialmente al manejar E / S mapeadas en memoria o puede considerarse una situación de matriz simple), por lo que se recomienda encarecidamente especificar variables de tamaño fijo. En los sistemas heredados puede encontrarse

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

A partir de C99, los diseñadores agregaron el archivo de encabezado stdint.h que esencialmente aprovecha typedefs similares.

En un sistema basado en Windows, puede ver entradas en el archivo de encabezado stdin.h como

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

Hay mucho más en eso, como entero de ancho mínimo o tipos de entero de ancho exacto, creo que no es malo explorar stdint.h para una mejor comprensión.

Naumann
fuente
1
Su código tiene un error tipográfico:, typedef short INT16;no typedefs short INT16.
Galaxy