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 el compilador.
¿Pero hay algún estándar 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
He intentado encontrar, sin mucho éxito, la información fiable según los tamaños de char
, short
, int
, long
, double
, float
(y otros tipos que no pensaron) en diferentes arquitecturas y compiladores.
int16_t
,int32_t
yint64_t
(necesitoiostream
incluirlo si no recuerdo mal). Lo bueno de esto es que int64_t no debería tener problemas en un sistema de 32 bits (aunque esto afectará el rendimiento).<cstdint>
, no<iostream>
.Respuestas:
El estándar C ++ no especifica el tamaño de los tipos integrales en bytes, pero especifica los 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 el 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 menor que 8. Esto se debe a que debe ser lo suficientemente grande como para contener "las unidades de código de ocho bits de la forma de codificación Unicode UTF-8".Una restricción adicional para
char
es que su tamaño es siempre de 1 byte oCHAR_BIT
bits (de ahí el nombre). Esto se establece 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 los rangos de tipo de datos en MSDN :
signed char
: -127 a 127 (nota, no -128 a 127; esto se adapta a plataformas de complemento y signo y magnitud de 1)unsigned char
: 0 a 255char
: mismo rango quesigned char
ounsigned char
, definido por la implementaciónsigned 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 18446744073709551615Una implementación de C ++ (o C) puede definir el tamaño de un tipo en bytes
sizeof(type)
a cualquier valor, siempre quesizeof(type) * CHAR_BIT
evalúa en un número de bits lo suficientemente alto como para contener los rangos requeridos, ysizeof(int) <= sizeof(long)
. ej .).Al unir todo esto, tenemos la garantía de que:
char
,signed char
yunsigned char
son al menos 8 bitssigned short
,unsigned short
,signed int
, Yunsigned int
son al menos 16 bitssigned long
yunsigned long
son al menos 32 bitssigned long long
yunsigned long long
son al menos 64 bitsNo se ofrece ninguna garantía sobre el tamaño de,
float
odouble
excepto, quedouble
proporcione al menos tanta precisión comofloat
.Los rangos específicos de implementación reales se pueden encontrar en el
<limits.h>
encabezado en C, o<climits>
en C ++ (o incluso mejor,std::numeric_limits
en el<limits>
encabezado).Por ejemplo, así es como encontrará el rango máximo para
int
:C:
C ++ :
fuente
char
", y no el significado habitual.Para los sistemas de 32 bits, el estándar 'de facto' es ILP32, es decir
int
,long
y el puntero son todas las cantidades de 32 bits.Para los sistemas de 64 bits, el estándar principal de facto de Unix es LP64,
long
y el puntero es de 64 bits (peroint
es de 32 bits). El estándar de Windows de 64 bits es LLP64 -long long
y el puntero de 64 bits (perolong
yint
son ambos de 32 bits).Hubo un tiempo en que algunos sistemas Unix usaban una organización ILP64.
Ninguno de estos estándares de facto está legislado por el estándar C (ISO / IEC 9899: 1999), pero todos están permitidos por él.
Y, por definición,
sizeof(char)
es1
, 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 mayor que 8. Eso significa, IIRC, quesizeof(int)
también fue 1, debido a que tantochar
yint
eran de 32 bits.fuente
[u]int32_t
o similar, si desea un uso de 64 bits[u]int64_t
... si no tiene un encabezado para ellos, descargue o haga uno, preferiblemente con la selección de tiempo de compilación de tales tipos o aserciones estáticas para verificar el tamaño. pubs.opengroup.org/onlinepubs/009695299/basedefs/stdint.h.html Si los tamaños precisos no son tan importantes y solo le importa que sean al menos tan grandes, entonces su consejo es válido para las plataformas modernas comunes de PC / servidor.int get_char(FILE *fp, char *c)
que devuelve EOF o 0 y establece*c
.uint32_t x=1,y=2;
el valor dex-y
debe ser 4294967295 en plataformas donde "int" es 32 bits o menor, y -1 en plataformas donde "int" es 33 bits o mayor. Además, requiere quex*y
se evalúe usando aritmética modular para todos los valores de x e y si "int" es 32 bits o más pequeño, y la aritmética convencional si es de 65 bits o más, pero no establece ningún requisito sobre lo que puede suceder con valores grandes de x e y si "int" es de 33 a 64 bits.En la práctica no existe tal cosa. A menudo puede esperar
std::size_t
representar el tamaño entero nativo sin signo en la arquitectura actual. es decir, 16 bits, 32 bits o 64 bits, pero no siempre es el caso como se señala en los comentarios a esta respuesta.En cuanto a todos los demás tipos incorporados, realmente depende del compilador. Aquí hay dos extractos del borrador actual del último estándar de C ++:
Si lo desea, puede afirmar estáticamente (tiempo de compilación) el tamaño de estos tipos fundamentales. Alertará a las personas a pensar en portar su código si cambia el tamaño de las suposiciones.
fuente
Hay estándar.
El estándar C90 requiere que
El estándar C99 requiere que
Aquí están las especificaciones C99 . La página 22 detalla los tamaños de los diferentes tipos integrales.
Aquí están los tamaños de tipo int (bits) para plataformas Windows:
Si le preocupa la portabilidad o desea que el nombre del tipo refleje el tamaño, puede mirar el encabezado
<inttypes.h>
, donde están disponibles las siguientes macros:int8_t
tiene una garantía de 8 bits yint16_t
16 bits, etc.fuente
sizeof(long) < sizeof(long long)
en lugar del simétricosizeof(long) <= sizeof(long long)
?Si necesita tipos de tamaño fijo, use tipos como uint32_t (entero sin signo de 32 bits) definidos en stdint.h . Se especifican en C99 .
fuente
CHAR_BIT == 16
, por ejemplo, no tendráint8_t
. Cualquier plataforma que no use el complemento de dos no tendrá ninguno de ellos (ya que el estándar requiere el complemento de dos).Actualizado: C ++ 11 trajo los tipos de TR1 oficialmente al estándar:
Y los tipos "dimensionados" de
<cstdint>
Además obtienes:
Estos tipos representan los tipos enteros más pequeños con al menos el número especificado de bits. Del mismo modo, existen los tipos enteros "más rápidos" con al menos el número especificado de bits:
Lo que significa "rápido", en todo caso, depende de la implementación. No necesita ser el más rápido para todos los propósitos tampoco.
fuente
El estándar C ++ lo dice así:
3.9.1, §2:
La conclusión: depende de la arquitectura en la que esté trabajando. Cualquier otra suposición es falsa.
fuente
No, no hay un estándar para los tamaños de letra. El estándar solo requiere que:
Lo mejor que puede hacer si desea variables de un tamaño fijo es usar macros como este:
Luego puede usar WORD para definir sus variables. No es que me guste, pero es la forma más portátil .
fuente
#include <boost/cstdint.hpp>
Se nos permite definir un sinónimo para el tipo para que podamos crear nuestro propio "estándar".
En una máquina en la que sizeof (int) == 4, podemos definir:
Entonces, cuando transferimos el código a una máquina diferente donde en realidad el tamaño de int largo es 4, podemos redefinir la ocurrencia única de int.
fuente
<stdint.h>
(C99 y posterior, y cualquiera que sea el estándar C ++ adoptó la versión C99 de la biblioteca C).Para los números de coma flotante hay un estándar (IEEE754) : los flotantes son de 32 bits y los dobles son 64. Este es un estándar de hardware, no un estándar de C ++, por lo que los compiladores teóricamente podrían definir flotante y duplicar a otro tamaño, pero en la práctica I ' Nunca he visto una arquitectura que usara algo diferente.
fuente
double
tiene el mismo tamaño quefloat
(yint
el mismo quechar
ambos son de 16 bits). Pero tienen un 64 bitlong double
.Existe un estándar y se especifica en los diversos documentos de estándares (ISO, ANSI y demás).
Wikipedia tiene una gran página que explica los diversos tipos y el máximo que pueden almacenar: Integer in Computer Science.
Sin embargo, incluso con un compilador estándar de C ++, puede averiguarlo con relativa facilidad utilizando el siguiente fragmento de código:
La documentación para std :: numeric_limits se puede encontrar en Roguewave . Incluye una gran cantidad de otros comandos a los que puede llamar para conocer los diversos límites. Esto se puede usar con cualquier tipo arbitrario que transmita tamaño, por ejemplo std :: streamsize.
La respuesta de John contiene la mejor descripción, ya que están garantizadas. No importa en qué plataforma se encuentre, hay otra buena página que detalla cuántos bits DEBE contener cada tipo: tipos int , que se definen en el estándar.
¡Espero que esto ayude!
fuente
1) Tabla N1 en el artículo " Los problemas olvidados del desarrollo de programas de 64 bits "
2) " Modelo de datos "
fuente
Puedes usar:
datatype = int
,long int
etc. Podrá ver el tamaño del tipo de datos que escriba.fuente
Cuando se trata de tipos incorporados para diferentes arquitecturas y diferentes compiladores, simplemente ejecute el siguiente código en su arquitectura con su compilador para ver qué produce. A continuación se muestra mi Ubuntu 13.04 salida (Raring Ringtail) de 64 bits g ++ 4.7.3. También tenga en cuenta lo que se respondió a continuación, por lo que la salida se ordena como tal:
"Hay cinco tipos enteros con signo estándar: char con signo, int corto, int, largo int y largo largo int. En esta lista, cada tipo proporciona al menos tanto almacenamiento como los que le preceden en la lista".
fuente
sizeof(char)
No debe ser incluido.Como se mencionó, el tamaño debe reflejar la arquitectura actual. Podrías echar un
limits.h
vistazo si quieres ver cómo tu compilador actual está manejando las cosas.fuente
Como han respondido otros, todos los "estándares" dejan la mayoría de los detalles como "implementación definida" y solo indican que el tipo "char" está al menos "char_bis" de ancho, y que "char <= short <= int <= long < = long long "(float y double son bastante consistentes con los estándares de coma flotante IEEE, y long double suele ser lo mismo que double, pero puede ser mayor en implementaciones más actuales).
Parte de las razones para no tener valores muy específicos y exactos se debe a que los lenguajes como C / C ++ fueron diseñados para ser portátiles en una gran cantidad de plataformas de hardware, incluidos los sistemas informáticos en los que el tamaño de palabra "char" puede ser de 4 bits o 7 bits, o incluso algún valor distinto de las computadoras "8- / 16- / 32- / 64-bit" a las que está expuesto el usuario promedio de computadoras domésticas. (Tamaño de palabra aquí, lo que significa cuántos bits de ancho funciona normalmente el sistema; de nuevo, no siempre es de 8 bits como pueden esperar los usuarios de computadoras domésticas).
Si realmente necesita un objeto (en el sentido de una serie de bits que represente un valor integral) de un número específico de bits, la mayoría de los compiladores tienen algún método para especificarlo; Pero generalmente no es portátil, incluso entre compiladores hechos por la compañía ame, sino para diferentes plataformas. Algunos estándares y prácticas (especialmente los límites. H y similares) son lo suficientemente comunes como para que la mayoría de los compiladores tengan soporte para determinar en el tipo de mejor ajuste para un rango específico de valores, pero no el número de bits utilizados. (Es decir, si sabe que necesita mantener valores entre 0 y 127, puede determinar que su compilador admite un tipo "int8" de 8 bits que será lo suficientemente grande como para contener el rango completo deseado, pero no algo así como un tipo "int7", que sería una coincidencia exacta para 7 bits).
Nota: Muchos paquetes fuente Un * x utilizaron el script "./configure" que probará las capacidades del compilador / sistema y generará un Makefile y config.h adecuados. Puede examinar algunos de estos scripts para ver cómo funcionan y cómo prueban las capacidades del sistema / comiler, y seguir su ejemplo.
fuente
Si está interesado en una solución pura de C ++, utilicé plantillas y solo código estándar de C ++ para definir tipos en tiempo de compilación en función de su tamaño de bits. Esto hace que la solución sea portátil en todos los compiladores.
La idea detrás es muy simple: cree una lista que contenga tipos char, int, short, long, long long (versiones con y sin signo) y escanee la lista y mediante el uso de la plantilla numeric_limits seleccione el tipo con el tamaño dado.
Incluyendo este encabezado tienes 8 tipos stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64.
Si algún tipo no se puede representar, se evaluará como stdtype :: null_type también declarado en ese encabezado.
EL CÓDIGO A CONTINUACIÓN SE OTORGA SIN GARANTÍA, POR FAVOR REVISE DOBLE.
SOY NUEVO EN METAPROGRAMMING TAMBIÉN, NO DEBE EDITAR Y CORREGIR ESTE CÓDIGO.
Probado con DevC ++ (por lo que una versión de gcc alrededor de 3.5)
fuente
donde
X
está unachar
,int
,long
etc .. le dará tamaño deX
en bits.fuente
sizeof(type)*CHAR_BIT
mantieneCHAR_BIT
se garantizara que fueran 8 bits,<< 3
es simplemente una forma ofuscada de escribir* 8
o* CHAR_BIT
.De Alex B El estándar C ++ no especifica el tamaño de los tipos integrales en bytes, pero especifica los 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 el valor de la macro CHAR_BIT que define el número de bits en un byte (en todas las plataformas menos oscuras es 8, y no puede ser inferior a 8).
Una restricción adicional para char es que su tamaño siempre es de 1 byte, o bits CHAR_BIT (de ahí el nombre).
Los rangos mínimos requeridos por el estándar (página 22) son:
y rangos de tipo de datos en MSDN:
char firmado: -127 a 127 (nota, no -128 a 127; esto acomoda plataformas de complemento de 1) char sin firmar: 0 a 255 char "normal": -127 a 127 o 0 a 255 (depende de la firma de char predeterminada) firmado corto: -32767 a 32767 sin signo corto: 0 a 65535 con signo int: -32767 a 32767 sin signo int: 0 a 65535 con signo largo: -2147483647 a 2147483647 sin signo largo: 0 a 4294967295 con signo largo largo: -9223372036854775807 a 9223372036854775807 sin signo largo 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 evalúa el número de bits suficiente para contener los rangos requeridos, y el orden del tipo sigue siendo válido (por ejemplo, sizeof (int) <= sizeof (long)). Los rangos específicos de implementación reales se pueden encontrar en el encabezado en C, o en C ++ (o incluso mejor, std :: numeric_limits en el encabezado).
Por ejemplo, así es como encontrará el rango máximo para int:
C:
C ++:
Esto es correcto, sin embargo, también tenía razón al decir que: char: 1 byte corto: 2 bytes int: 4 bytes de largo: 4 bytes flotante: 4 bytes doble: 8 bytes
Debido a que las arquitecturas de 32 bits siguen siendo las predeterminadas y más utilizadas, y han mantenido estos tamaños estándar desde los días anteriores a 32 bits cuando la memoria estaba menos disponible, y para la compatibilidad y estandarización hacia atrás permaneció igual. Incluso los sistemas de 64 bits tienden a usar estos y tienen extensiones / modificaciones. Consulte esto para obtener más información:
http://en.cppreference.com/w/cpp/language/types
fuente
Noté que todas las otras respuestas aquí se han centrado casi exclusivamente en tipos integrales, mientras que el interrogador también preguntó sobre los puntos flotantes.
No creo que el estándar C ++ lo requiera, pero los compiladores para las plataformas más comunes en estos días generalmente siguen el estándar IEEE754 para sus números de punto flotante. Este estándar especifica cuatro tipos de punto flotante binario (así como algunos formatos BCD, para los cuales nunca he visto soporte en compiladores C ++):
¿Cómo se asigna esto a los tipos C ++, entonces? Generalmente los
float
usos de precisión simple; Por lo tanto,sizeof(float) = 4
. Luegodouble
usa doble precisión (creo que esa es la fuente del nombredouble
), ylong double
puede ser de precisión doble o cuádruple (es cuádruple en mi sistema, pero en sistemas de 32 bits puede ser doble). No conozco ningún compilador que ofrezca puntos flotantes de precisión media.En resumen, esto es lo habitual:
sizeof(float)
= 4sizeof(double)
= 8sizeof(long double)
= 8 o 16fuente
Como mencionó, depende en gran medida del compilador y la plataforma. Para esto, consulte el estándar ANSI, http://home.att.net/~jackklein/c/inttypes.html
Aquí está el del compilador de Microsoft: Rangos de tipo de datos .
fuente
Puede usar variables proporcionadas por bibliotecas como OpenGL , Qt , etc.
Por ejemplo, Qt proporciona qint8 (con garantía de 8 bits en todas las plataformas compatibles con Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.
fuente
En una máquina de 64 bits:
fuente
int
es de 8 bytes, pero el otro no está garantizado. No hay nada que diga quechar
debería ser solo 8 bits. Está permitido tenerlosizeof(void*)==4
aunque sea de 64 bits.Hay cuatro tipos de enteros según el tamaño:
fuente
short
,int
ylong
todos los enteros de 32 bits.int
, no la palabra "entero".