¿Qué indica el estándar de C ++ el tamaño de int, long type to be?

Estoy buscando información detallada sobre el tamaño de los tipos básicos de C ++. Sé que depende de la architecture (16 bits, 32 bits, 64 bits) y el comstackdor.

Pero, ¿hay algún estándar para C ++?

Estoy usando Visual Studio 2008 en una architecture 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 

Traté de encontrar, sin mucho éxito, información confiable que indicara los tamaños de char , short , int , long , double , float (y otros tipos que no pensé) bajo diferentes architectures y comstackdores.

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 deducir el tamaño mínimo en bytes de eso y el valor de la macro CHAR_BIT 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).

Una restricción adicional para char es que su tamaño es siempre 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 tipos de datos en MSDN :

  1. signed char : -127 a 127 (nota, no -128 a 127; esto acomoda las plataformas de complemento y de signo y magnitud de 1)
  2. unsigned char : 0 a 255
  3. char “simple”: el mismo rango que signed char o unsigned char , definido por la implementación
  4. signed short : -32767 a 32767
  5. unsigned short : 0 a 65535
  6. signed int : -32767 a 32767
  7. unsigned int : 0 a 65535
  8. signed long : -2147483647 a 2147483647
  9. unsigned long : 0 a 4294967295
  10. signed long long : -9223372036854775807 a 9223372036854775807
  11. unsigned long long : 0 a 18446744073709551615

Una implementación C ++ (o C) puede definir el tamaño de un tipo en bytes sizeof(type) a cualquier valor, siempre que

  1. la expresión sizeof(type) * CHAR_BIT evalúa una cantidad de bits lo suficientemente alta como para contener los rangos requeridos, y
  2. el orden de 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 mejor aún, std::numeric_limits con std::numeric_limits en el std::numeric_limits ).

Por ejemplo, así es como encontrará el rango máximo para int :

DO:

 #include  const int min_int = INT_MIN; const int max_int = INT_MAX; 

C ++ :

 #include  const int min_int = std::numeric_limits::min(); const int max_int = std::numeric_limits::max(); 

Para los sistemas de 32 bits, el estándar ‘de facto’ es ILP32, es decir, int , long y puntero son todas las cantidades de 32 bits.

Para los sistemas de 64 bits, el estándar primario de facto de Unix es LP64 – long y el puntero son de 64 bits (pero int es de 32 bits). El estándar de Windows de 64 bits es LLP64: long long y puntero de 64 bits (pero long e int son ambos de 32 bits).

En un momento, 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) 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 tanto char como int eran 32 bits.

En la práctica, no existe tal cosa. A menudo puede esperar que std::size_t represente el tamaño entero nativo sin firmar en la architecture 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 comstackdor. Aquí hay dos extractos tomados del borrador de trabajo actual del último estándar de C ++:

Hay cinco tipos de entero con signo estándar: char firmado, int corto, int, int largo y int largo largo. En esta lista, cada tipo proporciona al menos tanto almacenamiento como los que lo preceden en la lista.

Para cada uno de los tipos de entero con signo estándar, existe un tipo de entero estándar sin signo correspondiente (pero diferente): unsigned char, unsigned short int, unsigned int, unsigned long int y unsigned long long int, cada uno de los cuales ocupa la misma cantidad de almacenamiento y tiene los mismos requisitos de alineación.

Si lo desea, puede afirmar estáticamente (en tiempo de comstackción) el tamaño de estos tipos fundamentales. Alertará a las personas a pensar en portar su código si el tamaño de las suposiciones cambia.

Hay un estándar

El estándar C90 requiere que

 sizeof(short) < = sizeof(int) <= sizeof(long) 

El estándar C99 requiere que

 sizeof(short) < = sizeof(int) <= sizeof(long) <= sizeof(long long) 

Aquí están las especificaciones C99 . Página 22 detalles de tamaños de diferentes tipos integrales.

Aquí están los tamaños de tipo int (bits) para las plataformas de Windows:

 Type C99 Minimum Windows 32bit char 8 8 short 16 16 int 16 32 long 32 32 long long 64 64 

Si le preocupa la portabilidad, o si desea que el nombre del tipo refleje el tamaño, puede ver el encabezado , donde están disponibles las siguientes macros:

 int8_t int16_t int32_t int64_t 

int8_t tiene garantizado 8 bits, y int16_t garantiza 16 bits, etc.

Si necesita tipos de tamaño fijo, utilice tipos como uint32_t (entero sin signo de 32 bits) definido en stdint.h . Están especificados en C99 .

Actualizado: C ++ 11 trajo oficialmente los tipos de TR1 al estándar:

  • largo largo int
  • unsigned long long int

Y los tipos “dimensionados” de

  • int8_t
  • int16_t
  • int32_t
  • int64_t
  • (y las contrapartes sin firmar).

Además, obtienes:

  • int_least8_t
  • int_least16_t
  • int_least32_t
  • int_least64_t
  • Además de las contrapartes sin firmar.

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:

  • int_fast8_t
  • int_fast16_t
  • int_fast32_t
  • int_fast64_t
  • Además de las versiones sin firmar.

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.

El estándar C ++ lo dice así:

3.9.1, §2:

Hay cinco tipos de entero con signo: “signed char”, “short int”, “int”, “long int” y “long long int”. En esta lista, cada tipo proporciona al menos tanto almacenamiento como los que lo preceden en la lista. Las aplicaciones simples tienen el tamaño natural sugerido por la architecture del entorno de ejecución (44); los otros tipos de entero con signo se proporcionan para satisfacer necesidades especiales.

(44) es decir, lo suficientemente grande como para contener cualquier valor en el rango de INT_MIN e INT_MAX, como se define en el encabezado .

La conclusión: depende de la architecture en la que estés trabajando. Cualquier otra suposición es falsa.

No, no hay un estándar para los tamaños de letra. El estándar solo requiere que:

 sizeof(short int) < = sizeof(int) <= sizeof(long int) 

Lo mejor que puede hacer si quiere variables de un tamaño fijo es usar macros como esta:

 #ifdef SYSTEM_X #define WORD int #else #define WORD long int #endif 

Entonces puedes usar WORD para definir tus variables. No es que me guste esto, pero es la forma más portátil .

Estamos autorizados a 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:

 typedef int int32; int32 i; int32 j; ... 

Entonces, cuando transferimos el código a una máquina diferente donde en realidad el tamaño de int largo es 4, podemos simplemente redefinir la única ocurrencia de int.

 typedef long int int32; int32 i; int32 j; ... 

Para los números flotantes 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 comstackdores teóricamente pueden definir float y double a algún otro tamaño, pero en la práctica I ‘ Nunca he visto una architecture que usara algo diferente.

Hay un estándar y está especificado en varios documentos de estándares (ISO, ANSI y otras cosas).

Wikipedia tiene una gran página que explica los diversos tipos y el máximo que pueden almacenar: Entero en Ciencias de la Computación.

Sin embargo, incluso con un comstackdor estándar de C ++, puedes descubrirlo de manera relativamente fácil con el siguiente fragmento de código:

 #include  #include  int main() { // Change the template parameter to the various different types. std::cout < < std::numeric_limits::max() < < std::endl; } 

La documentación para std :: numeric_limits se puede encontrar en Roguewave . Incluye una plétora de otros comandos 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 garantizados. Independientemente de la plataforma en la que se encuentre, hay otra buena página que detalla cuántos bits debe contener cada tipo: tipos int , que están definidos en el estándar.

¡Espero que esto ayude!

1) Tabla N1 en el artículo ” Los problemas olvidados del desarrollo de progtwigs de 64 bits ”

2) ” Modelo de datos ”

Puedes usar:

 cout < < "size of datatype = " << sizeof(datatype) << endl; 

datatype = int , long int etc. Podrá ver el tamaño de cualquier tipo de datos que escriba.

Cuando se trata de tipos integrados para diferentes architectures y diferentes comstackdores, simplemente ejecute el siguiente código en su architecture con su comstackdor para ver qué produce. A continuación se muestra mi Ubuntu 13.04 (Raring Ringtail) 64 bits g ++ 4.7.3 de salida. También tenga en cuenta lo que se respondió a continuación, que es por qué la salida se ordena como tal:

“Hay cinco tipos de enteros con signo estándar: con signo char, short int, int, long int y long long int. En esta lista, cada tipo proporciona al menos tanto almacenamiento como los que lo preceden en la lista”.

 #include  int main ( int argc, char * argv[] ) { std::cout< < "size of char: " << sizeof (char) << std::endl; std::cout<< "size of short: " << sizeof (short) << std::endl; std::cout<< "size of int: " << sizeof (int) << std::endl; std::cout<< "size of long: " << sizeof (long) << std::endl; std::cout<< "size of long long: " << sizeof (long long) << std::endl; std::cout<< "size of float: " << sizeof (float) << std::endl; std::cout<< "size of double: " << sizeof (double) << std::endl; std::cout<< "size of pointer: " << sizeof (int *) << std::endl; } size of char: 1 size of short: 2 size of int: 4 size of long: 8 size of long long: 8 size of float: 4 size of double: 8 size of pointer: 8 

Como se mencionó, el tamaño debe reflejar la architecture actual. Podría tomar un pico en limits.h Si desea ver cómo su comstackdor actual está manejando cosas.

Como otros han respondido, 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” ancho, y que “char < = short <= int <= long < = long long "(el flotante y el doble son bastante consistentes con los estándares de punto flotante IEEE, y el doble largo suele ser el mismo que el doble, pero puede ser mayor en las implementaciones más actuales).

Parte de las razones para no tener valores muy específicos y exactos es porque los lenguajes como C / C ++ fueron diseñados para ser portátiles en un gran número 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 que no sean las computadoras “8/16/32/64 bits” a las que está expuesto el usuario promedio de la computadora hogareña. (Aquí el tamaño de palabra significa la cantidad de bits de ancho con los que normalmente opera el sistema; una vez más, no siempre son 8 bits como pueden esperar los usuarios de la computadora hogareña).

Si realmente necesita un objeto (en el sentido de una serie de bits que representa un valor integral) de un número específico de bits, la mayoría de los comstackdores tienen algún método para especificar eso; Pero, en general, no es portátil, incluso entre comstackdores hechos por la empresa ame pero 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 comstackdores tengan soporte para determinar el tipo de mejor ajuste para un rango específico de valores, pero no la cantidad de bits utilizados. (Es decir, si sabe que necesita mantener valores entre 0 y 127, puede determinar que su comstackdor admite un tipo “int8” de 8 bits que será lo suficientemente grande como para mantener 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 usaron el script “./configure” que sondeará las capacidades del comstackdor / sistema y generará un Makefile y config.h adecuados. Puede examinar algunos de estos scripts para ver cómo funcionan y cómo exploran las capacidades del comiler / sistema, y ​​seguir su ejemplo.

Si está interesado en una solución pura de C ++, hice uso de plantillas y solo código estándar de C ++ para definir los tipos en tiempo de comstackción en función de su tamaño de bit. Esto hace que la solución sea portátil entre los comstackdores.

La idea detrás es muy simple: cree una lista que contenga tipos char, int, corto, largo, largo y largo (versiones firmadas y sin firmar) y escanee la lista y, mediante el uso de la plantilla numeric_limits, seleccione el tipo con un tamaño determinado.

Incluyendo este encabezado, obtuvo 8 tipo stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64.

Si no se puede representar algún tipo, se evaluará a stdtype :: null_type también declarado en ese encabezado.

EL CÓDIGO A CONTINUACIÓN SE ENTREGA SIN GARANTÍA, POR FAVOR, DÉJELO COMPROBARLO.
SOY NUEVO EN METAPROGRAMANDO TAMBIÉN, Siéntase libre de EDITAR Y CORREGIR ESTE CÓDIGO.
Probado con DevC ++ (por lo que una versión de gcc alrededor de 3.5)

 #include  namespace stdtype { using namespace std; /* * THIS IS THE CLASS USED TO SEMANTICALLY SPECIFY A NULL TYPE. * YOU CAN USE WHATEVER YOU WANT AND EVEN DRIVE A COMPILE ERROR IF IT IS * DECLARED/USED. * * PLEASE NOTE that C++ std define sizeof of an empty class to be 1. */ class null_type{}; /* * Template for creating lists of types * * T is type to hold * S is the next type_list type * * Example: * Creating a list with type int and char: * typedef type_list > test; * test::value //int * test::next::value //char */ template  struct type_list { typedef T value; typedef S next; }; /* * Declaration of template struct for selecting a type from the list */ template  struct select_type; /* * Find a type with specified "b" bit in list "list" * * */ template  struct find_type { private: //Handy name for the type at the head of the list typedef typename list::value cur_type; //Number of bits of the type at the head //CHANGE THIS (compile time) exp TO USE ANOTHER TYPE LEN COMPUTING enum {cur_type_bits = numeric_limits::digits}; public: //Select the type at the head if b == cur_type_bits else //select_type call find_type with list::next typedef typename select_type::type type; }; /* * This is the specialization for empty list, return the null_type * OVVERRIDE this struct to ADD CUSTOM BEHAVIOR for the TYPE NOT FOUND case * (ie search for type with 17 bits on common archs) */ template  struct find_type { typedef null_type type; }; /* * Primary template for selecting the type at the head of the list if * it matches the requested bits (b == ctl) * * If b == ctl the partial specified templated is evaluated so here we have * b != ctl. We call find_type on the next element of the list */ template  struct select_type { typedef typename find_type::type type; }; /* * This partial specified templated is used to select top type of a list * it is called by find_type with the list of value (consumed at each call) * the bits requested (b) and the current type (top type) length in bits * * We specialice the b == ctl case */ template  struct select_type { typedef typename list::value type; }; /* * These are the types list, to avoid possible ambiguity (some weird archs) * we kept signed and unsigned separated */ #define UNSIGNED_TYPES type_list > > > > #define SIGNED_TYPES type_list > > > > /* * These are acutally typedef used in programs. * * Nomenclature is [u]intN where u if present means unsigned, N is the * number of bits in the integer * * find_type is used simply by giving first a type_list then the number of * bits to search for. * * NB. Each type in the type list must had specified the template * numeric_limits as it is used to compute the type len in (binary) digit. */ typedef find_type::type uint8; typedef find_type::type uint16; typedef find_type::type uint32; typedef find_type::type uint64; typedef find_type::type int8; typedef find_type::type int16; typedef find_type::type int32; typedef find_type::type int64; } 
 unsigned char bits = sizeof(X) < < 3; 

donde X es un char , int , long , etc. le dará el tamaño de X en bits.

Desde 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 deducir el tamaño mínimo en bytes de eso y el valor de la macro CHAR_BIT 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).

Una restricción adicional para char es que su tamaño es siempre 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 tipos de datos en MSDN:

char firmado: -127 a 127 (nota, no -128 a 127; esto acomoda plataformas de complemento a 1) char sin firmar: 0 a 255 char “simple”: -127 a 127 o 0 a 255 (depende de la firma predeterminada) firmado cortocircuito: -32767 a 32767 corto sin firmar: 0 a 65535 firmado int: -32767 a 32767 sin signo int: 0 a 65535 largo con signo: -2147483647 a 2147483647 sin signo largo: 0 a 4294967295 largo con signo largo: -9223372036854775807 a 9223372036854775807 largo sin signo: 0 a 18446744073709551615 Una implementación C ++ (o C) puede definir el tamaño de un tipo en bytes sizeof (tipo) a cualquier valor, siempre que

la expresión sizeof (tipo) * CHAR_BIT evalúa la cantidad de bits suficientes para contener los intervalos requeridos, y el orden de tipo sigue siendo válido (por ejemplo, sizeof (int) < = sizeof (long)). Los rangos específicos de la implementación real se pueden encontrar en el encabezado en C, o en C ++ (o mejor aún, templado std :: numeric_limits en el encabezado).

Por ejemplo, así es como encontrará el rango máximo para int:

DO:

 #include  const int min_int = INT_MIN; const int max_int = INT_MAX; 

C ++:

 #include  const int min_int = std::numeric_limits::min(); const int max_int = std::numeric_limits::max(); 

Esto es correcto, sin embargo, también tenías razón al decir que: char: 1 byte corto: 2 bytes int: 4 bytes de longitud: 4 bytes flotantes: 4 bytes dobles: 8 bytes

Debido a que las architectures de 32 bits siguen siendo las predeterminadas y las más utilizadas, y han conservado estos tamaños estándar desde los días anteriores a los 32 bits cuando la memoria estaba menos disponible, y por la compatibilidad con versiones anteriores y la estandarización, permanecieron iguales. Incluso los sistemas de 64 bits tienden a usarlos y tienen extensiones / modificaciones. Por favor, consulte esto para más información:

http://en.cppreference.com/w/cpp/language/types

Observo que todas las demás respuestas aquí se han centrado casi exclusivamente en los tipos integrales, mientras que el que pregunta también ha preguntado acerca de los puntos flotantes.

No creo que el estándar C ++ lo requiera, pero los comstackdores de las plataformas más comunes en estos días generalmente siguen el estándar IEEE754 para sus números de coma flotante. Este estándar especifica cuatro tipos de puntos flotantes binarios (así como algunos formatos BCD, que nunca he visto compatibles con los comstackdores C ++):

  • Media precisión (binario16) – Significado de 11 bits, rango exponencial -14 a 15
  • Precisión simple (binario32) – Significado de 24 bits, rango exponencial -126 a 127
  • Doble precisión (binary64) – Significado de 53 bits, rango exponencial -1022 a 1023
  • Cuádruple precisión (binario128) – Significado de 113 bits, rango exponencial -16382 a 16383

¿Cómo funciona este mapa en tipos de C ++, entonces? En general, el float usa una sola precisión; por lo tanto, sizeof(float) = 4 . Luego el double usa doble precisión (creo que esa es la fuente del nombre double ), y el long double puede ser de precisión doble o cuádruple (es cuádruple en mi sistema, pero en sistemas de 32 bits puede ser el doble). No conozco ningún comstackdor que ofrezca puntos flotantes de precisión media.

En resumen, esto es lo habitual:

  • sizeof(float) = 4
  • sizeof(double) = 8
  • sizeof(long double) = 8 o 16

As you mentioned – it largely depends upon the compiler and the platform. For this, check the ANSI standard, http://home.att.net/~jackklein/c/inttypes.html

Here is the one for the Microsoft compiler: Data Type Ranges .

You can use variables provided by libraries such as OpenGL , Qt , etc.

For example, Qt provides qint8 (guaranteed to be 8-bit on all platforms supported by Qt), qint16, qint32, qint64, quint8, quint16, quint32, quint64, etc.

On a 64-bit machine:

 int: 4 long: 8 long long: 8 void*: 8 size_t: 8 

There are four types of integers based on size:

  • short integer: 2 byte
  • long integer: 4 byte
  • long long integer: 8 byte
  • integer: depends upon the compiler (16 bit, 32 bit, or 64 bit)