Pregunta ¿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 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

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 arquitecturas y compiladores.


628
2018-02-26 07:59


origen


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 del CHAR_BIT macro que define la cantidad 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 CHAR_BIT bits (de ahí el nombre).

Rangos mínimos requerido 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 plataformas de complemento y de signo y magnitud 1)
  2. unsigned char: De 0 a 255
  3. "llanura" char: el mismo rango que signed char o unsigned char, definido por la implementación
  4. signed short: -32767 a 32767
  5. unsigned short: De 0 a 65535
  6. signed int: -32767 a 32767
  7. unsigned int: De 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 de C ++ (o C) puede definir el tamaño de un tipo en bytes sizeof(type) a cualquier valor, siempre y cuando

  1. la expresion 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 (p. sizeof(int) <= sizeof(long))

Los rangos específicos de implementación reales se pueden encontrar en <limits.h> encabezado en C, o <climits> en C ++ (o incluso mejor, con plantillas std::numeric_limits en <limits> encabezamiento).

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

DO:

#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();

635
2018-02-26 08:47



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 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 el puntero son de 64 bits (pero long y 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 fue 1, porque ambos char y int eran de 32 bits.


209
2018-02-26 08:47



En la práctica, no existe tal cosa. A menudo puedes esperar std::size_tpara 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 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 compilació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.


80
2018-02-26 08:02



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 <inttypes.h>, donde están disponibles las siguientes macros:

int8_t
int16_t
int32_t
int64_t

int8_t se garantiza que es de 8 bits, y int16_t se garantiza que es de 16 bits, etc.


77
2018-03-30 14:49



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.


38
2018-02-26 08:18



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

  • largo largo int
  • unsigned long long int

Y los tipos "dimensionados" de <cstdint>

  • 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.


32
2018-02-26 19:32



los 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 aquellos que lo preceden   en la lista. Los ints llanos tienen   tamaño natural sugerido por el   arquitectura de la ejecución   medio ambiente (44); el otro firmado   tipos enteros se proporcionan para cumplir   necesidades especiales.

(44) eso es, lo suficientemente grande como para contener   cualquier valor en el rango de INT_MIN y   INT_MAX, como se define en el encabezado    <climits>.

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


17
2017-09-01 13:41



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 el más portátil camino.


12
2018-02-26 08:07



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;
...

9
2017-07-14 16:01



Para 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 compiladores teóricamente podrían definir float y double a algún otro tamaño, pero en la práctica nunca he visto una arquitectura que utilizara algo diferente.


8
2018-02-26 08:49