2009-04-09 18 views
19

Ocasionalmente necesito usar enteros de ancho fijo para la comunicación con dispositivos externos como PLC. También los utilizo para definir las máscaras de bits y realizar la manipulación de bits de los datos de imagen. AFAIK el estándar C99 define enteros de ancho fijo como int16_t. Sin embargo, el compilador que uso, VC++ 2008 no es compatible con C99 y AFAIK, Microsoft no tiene previsto apoyarlo.Enteros de ancho fijo en C++

Mi pregunta es ¿cuál es la mejor práctica para usar enteros de ancho fijo en C++?

Sé que VC++ define enteros de ancho fijo no estándar como __int16, pero dudo de usar un tipo no estándar. ¿El próximo estándar de C++ definirá enteros de ancho fijo?

Respuesta

12

Boost tiene las typedefs para todos los tipos C99 y más: "Boost integer library"

+1

Actualización para lectores reales: C++ 11 ahora tiene tipos de tamaño fijo: http://en.cppreference.com/w/cpp/types/integer – dkg

18

Puede solucionar el problema con algunas directivas #ifdef.

#ifdef _MSC_VER 
    typedef __int16 int16_t 
#else 
    #include <stdint.h> 
#endif 
+0

+1 ¡Solución inteligente, muy bien hecha! –

+3

¡Solo para su información futura, MSVC 2010 tiene ''! – Cameron

7

Incluya el archivo <stdint.h> para obtener las definiciones de tipos como uint16_t. VC++ no viene con <stdint.h> de forma predeterminada, pero puede obtener ese archivo desde varios lugares. Wikipedia enumera algunas, y Google encontrará mucho más.

+1

El problema es que stdint.h, como la mayoría o todos los encabezados C y C++, es específico de la implementación. Las definiciones dependen de la implementación. Cualquier encabezado aleatorio podría funcionar bien o fallar. –

+3

@David: Es un buen punto, pero en este caso los archivos stdint.h listados en la página de Wikipedia están escritos específicamente para MSVC++. –

+0

Ah, entonces no estamos hablando de encabezados aleatorios aquí. Bueno. –

3

¿El próximo estándar de C++ definirá los enteros de ancho fijo?

Sí.

Como dijo Mehrdad, puedes usar #ifdefs por el momento. Una alternativa sería una plantilla de magia elaborada. Boost tiene algo en esta dirección, el Boost Integer library.

0

Hay diferentes caminos a seguir. La mayoría de los entornos sostendrían que short int s son 16 bits, y long int s son 32. (El long está implícito cuando declara simplemente int.) Si tiene typedef su propio tipo int16, probablemente termine usando un short int.

Otra posibilidad radica en los campos de bit en las estructuras. Puede decir algo como:

struct x { 
    int a : 16; 
    int b : 5; 
    ... 
}; 

Y así sucesivamente. Si se definen así:

struct x myvar; 
myvar.a = 54; 

usted puede estar seguro de que myvar.a llevará a cabo de 16 bits, y myvar.b usarán 5; el tamaño total de myvar redondeando por lo que comprenden todos los bits, más, por supuesto, el tamaño de cualquier otro campo.

+0

corto suele ser de 16 bits, pero largo puede ser 32 o 64 bits en sistemas modernos. largo tiempo casi siempre será 64. –

+0

David tiene razón. Si sigues esta ruta, al menos incluiría algo como "assert (sizeof (short) == 2)" en algún lugar de tu código. –

+0

Longs en teoría puede ser de 64 bits. Nunca he trabajado con una máquina de 64 bits, pero mi impresión ha sido que la mayoría de los compiladores aún se mantienen en 32 y te obligan a usar mucho tiempo para 64. Lo más complicado es, creo, esto es todo definido por implementación independientemente de las convenciones . – Peter

1

He usado un dominio público (no GPL - cierto dominio público) versión de stdint.h por Danny Smith que está disponible en el paquete MinGW :

tuve que ajustar esa versión para compilar con algunos compiladores VC 8 (en su mayoría no VC6) - que ha servido yo bien.

Tal vez uno de estos días voy a conseguir publicar mi versión compatible con VC6 en alguna parte. Los cambios fueron bastante menores, solo algunos trucos de macro para usar palabras clave específicas de VC6 para tipos de 64 bits. Si no necesita soporte para VC6, la versión de mingw probablemente sea todo lo que necesite.

Cuestiones relacionadas