2009-09-06 18 views
11

A diferencia de Java o C#, los tipos de datos primitivos en C++ pueden variar en tamaño dependiendo de la plataforma. Por ejemplo, int no garantiza que sea un entero de 32 bits. Diversos entornos de compilación definen tipos de datos como uint32 o dword para este propósito, pero parece que no hay un archivo de inclusión estándar para tipos de datos de tamaño fijo.Tipos de datos primitivos multiplataforma en C++

¿Cuál es el método recomendado para lograr la máxima portabilidad?

Respuesta

11

me encontré con esta cabecera particularmente útil: BOOST cstdint

Por lo general, mejor que inventar propia rueda (que incurre en el mantenimiento y pruebas).

3

Defina un tipo (por ejemplo, int32) en un archivo de encabezado. Para cada plataforma use otro #ifdef y asegúrese de que in32 es un entero de 32 bits. Por todas partes en el uso de códigos int32 y asegúrese de que cuando se compila en diferentes plataformas que utiliza el derecho de definir

2

dos cosas:

En primer lugar, hay un archivo de cabecera llamada limits.h que da un montón de plataforma útil Información específica. Dará valores máximo y mínimo para el tipo int, por ejemplo. A partir de eso, puede deducir qué tan grande es el tipo int.

También puede usar el operador sizeof en tiempo de ejecución para estos fines.

Espero que esto ayude. . .

K

8

Crear un archivo de cabecera llamada types.h, y definir todos los tipos primitivos de tamaño fijo que necesita (int32, uint32, uint8, etc.). Para admitir plataformas múltiples, puede usar #ifdef o tener un directorio de inclusión separado para cada plataforma (include_x86, include_x86_64, include_sparc). En el último caso, tendría configuraciones de compilación separadas para cada plataforma, que tendría el directorio de incluir derecho en su ruta de inclusión. El segundo método es preferible, según "The C++ Gotchas" de Stephen Dewhurst.

Dejando a un lado, si está planeando pasar datos binarios entre diferentes plataformas, también debe preocuparse por el orden de los bytes.

5

Parte del estándar C99 era un archivo de encabezado stdint.h para proporcionar este tipo de información. Por ejemplo, define un tipo llamado uint32_t. Desafortunadamente, muchos compiladores no son compatibles con stdint.h. La mejor implementación multiplataforma que he visto de stdint.h está aquí: http://www.azillionmonkeys.com/qed/pstdint.h. Puedes simplemente incluir eso en tu proyecto.

Si usa boost, creo que también proporciona algo equivalente al encabezado stdint.

2

Hay un encabezado stdint.h definido por el estándar C99 y (creo) alguna variante u otra de ISO C++. Esto define buenos tipos como int16_t, uint64_t, etc ... que están garantizados para tener un tamaño y una representación específicos. Lamentablemente, su disponibilidad no es exactamente estándar (Microsoft, en particular, era un "dragger" aquí).

La respuesta simple es este, que funciona en cada arquitectura de byte-direccionable 32 o 64 bits Soy consciente de:

  • Todas las variables de carbonilla son 1 byte
  • Todas las variables cortos son 2 bytes
  • Todas las variables int son de 4 bytes
  • NO utilice un "largo", que es de tamaño indeterminado.
  • Todos los compiladores conocidos que admiten compatibilidad matemática de 64 bits permiten "larga duración" como tipo nativo de 64 bits.

Tenga en cuenta que algunos compiladores de 32 bits no tienen un tipo de 64 bits en absoluto, por lo que el uso a largo tiempo va a limitar a los sistemas de 64 bits y un conjunto más pequeño de los compiladores (que incluye gcc y MSVC, así que la mayoría a la gente no le importará este problema).

+1

he visto 'int' como de 64 bits en algunas plataformas. 'long long' no es estándar en C++ y solo se garantiza que tenga un tamaño igual o mayor que' long'. 'char', en algunos sistemas raros, es de 16 bits. Estas no son suposiciones portátiles que estás haciendo. Esta es la razón por la cual tanto software tiene problemas cuando se transfiere a 64 bits desde Win32 o Linux-32. – greyfade

+4

Este tipo de respuesta es la razón por la que comencé con la respuesta portátil. Pero lo siento, tu pedantería carece de evidencia. Soy consciente de que no hay plataforma en ninguna parte que defina int a 64 bits. "long long" es, de hecho, no estándar. Sin embargo, es divertido que sea mucho más portátil entre los compiladores que cualquier tipo estándar de 64 bits; me entristece que la gente no reconozca esto. El objetivo es la portabilidad, no estándares. Mi respuesta fue sobre preocupaciones de portabilidad práctica. –

1

Si su nombre comienza con dos guiones bajos (__), un tipo de datos no es estándar.

__int8 (__int8 sin firmar)

__int16 (__int16 sin firmar)

__int32 (__int32 sin firmar)

__int64 (__int64 sin firmar)

Intentar use realce/cstdint.hpp

Cuestiones relacionadas