¿Cuál establece el estándar C++ que debe ser el tamaño de tipo int, long?
Estoy buscando información detallada sobre el tamaño de los tipos básicos de C++. Sé que depende de la arquitectura (16 bits, 32 bits, 64 bits) y del compilador.
¿Pero existen estándares para C++?
Estoy usando Visual Studio 2008 en una arquitectura de 32 bits. Esto es lo que obtengo:
char : 1 byte
short : 2 bytes
int : 4 bytes
long : 4 bytes
float : 4 bytes
double: 8 bytes
Intenté encontrar, sin mucho éxito, información confiable que indicara los tamaños de char
, short
, int
, long
, double
( float
y otros tipos en los que no pensé) bajo diferentes arquitecturas y compiladores.
El estándar C++ no especifica el tamaño de los tipos integrales en bytes, pero especifica rangos mínimos que deben poder contener. Puede inferir el tamaño mínimo en bits del rango requerido. Puede inferir el tamaño mínimo en bytes a partir de eso y del valor de la CHAR_BIT
macro que define el número de bits en un byte . En todas las plataformas, excepto en las más oscuras, es 8, y no puede ser menos de 8.
Una restricción adicional char
es que su tamaño es siempre de 1 byte o CHAR_BIT
bits (de ahí el nombre). Esto está establecido explícitamente en la norma.
El estándar C es una referencia normativa para el estándar C++, por lo que, aunque no establece estos requisitos explícitamente, C++ requiere los rangos mínimos requeridos por el estándar C (página 22), que son los mismos que los de Rangos de tipos de datos en MSDN :
signed char
: -127 a 127 (nota, no -128 a 127; esto se adapta a plataformas en complemento a 1 y de signo y magnitud)unsigned char
: 0 a 255- "simple"
char
: mismo rango quesigned char
ounsigned char
, definido por la implementación signed short
: -32767 a 32767unsigned short
: 0 a 65535signed int
: -32767 a 32767unsigned int
: 0 a 65535signed long
: -2147483647 al 2147483647unsigned long
: 0 al 4294967295signed long long
: -9223372036854775807 a 9223372036854775807unsigned long long
: 0 a 18446744073709551615
Una implementación de C++ (o C) puede definir el tamaño de un tipo en bytes sizeof(type)
a cualquier valor, siempre que
- la expresión
sizeof(type) * CHAR_BIT
se evalúa como un número de bits lo suficientemente alto como para contener los rangos requeridos, y - el orden de tipo sigue siendo válido (p. ej.
sizeof(int) <= sizeof(long)
).
Si sumamos todo esto, tenemos la garantía de que:
char
,signed char
, yunsigned char
son de al menos 8 bitssigned short
,unsigned short
,signed int
, yunsigned int
son de al menos 16 bitssigned long
yunsigned long
son de al menos 32 bitssigned long long
yunsigned long long
son de al menos 64 bits
No se ofrece ninguna garantía sobre el tamaño de float
o double
excepto que double
proporcione al menos tanta precisión como float
.
Los rangos reales específicos de la implementación se pueden encontrar en <limits.h>
el encabezado en C o <climits>
en C++ (o incluso mejor, con plantilla std::numeric_limits
en <limits>
el encabezado).
Por ejemplo, así es como encontrará el 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, el estándar 'de facto' es ILP32, es decir, int
y long
el puntero son todas cantidades de 32 bits.
Para los sistemas de 64 bits, el principal estándar "de facto" de Unix es LP64, long
y el puntero es de 64 bits (pero int
es de 32 bits). El estándar de Windows de 64 bits es LLP64 long long
y el puntero es de 64 bits (pero long
ambos int
son de 32 bits).
Hubo un tiempo en que algunos sistemas Unix utilizaban una organización ILP64.
Ninguna de estas normas de facto está regulada por la norma C (ISO/IEC 9899:1999), pero todas están permitidas por ella.
Y, por definición, sizeof(char)
lo es 1
, a pesar de la prueba en el script de configuración de Perl.
Tenga en cuenta que había máquinas (Crays) donde CHAR_BIT
era mucho más grande que 8. Eso significaba, IIRC, que sizeof(int)
también era 1, porque ambos char
y int
eran de 32 bits.