2012-09-17 25 views
31

Tengo una base de código de código abierto que está escrita tanto en C como en C++. Estoy buscando un tipo entero que garantice que sea al menos de 64 bits de ancho, que se puede compilar confiablemente en la mayoría de los sistemas operativos OS X (Intel, 64 bits) y Linux con compiladores C y C++ de código abierto, sin demasiado trabajo adicional en la parte del usuario final. Windows y el soporte al cliente de 32 bits no son importantes en este momento.¿Debo usar long long o int64_t para código portable?

Hice algunas pruebas en OS X, y el último GCC que se incluye con las herramientas de desarrollador no es compatible con el modo C + 11 (y por lo tanto no parece garantizar la disponibilidad de long long). Clang tampoco es compatible con esto, aunque admite long long si el modo C99 está habilitado, después de cierta versión.

¿Es la sugerencia general de utilizar int64_t en lugar de long long, cuando la portabilidad es un objetivo importante? Usar los especificadores de formato parece doloroso.

¿Puedo fiable emitir un int64_t a long long (y del mismo modo a la unsigned equivalente con uint64_t) para utilizarlo con las funciones y bibliotecas existentes que toman como parámetros long long? (Y viceversa, por supuesto)

En ese estado de ánimo, si envío un código que requiera la funcionalidad de Clang y no en GCC, ¿Clang va a reemplazar a GCC como el compilador de elección en Linux? ¿Es ese compilador algo que puedo esperar, en su mayor parte, al ofrecer código fuente a los usuarios finales?

Básicamente, me gustaría pedir algunos consejos de otros desarrolladores que han utilizado ambos tipos de códigos C y C++ portátiles, que podrían tener algunas sugerencias sobre cuál podría ser el mejor camino a largo plazo, dado el por encima del objetivo en mente.

+0

gcc ha tenido 'long' larga como una extensión antes de C++ 11, así que mientras no desactivar gcc-extensiones que debe estar bien con el uso de' larga long' en gcc (En realidad no creo He utilizado/visto un compilador que no ofrece mucho tiempo por mucho tiempo). – Grizzly

+0

Tenga en cuenta que 'int64_t' puede tener el tipo subyacente' long' o 'long long' entre otros, lo que puede causar problemas de portabilidad si se necesita una sobrecarga. –

+0

Considere también typedef para realizar cambios sencillos de una plataforma a otra. – imallett

Respuesta

26

Los tipos long long y unsigned long long son tipos estándar C y C++ estándar, cada uno con al menos 64 bits. Todos los compiladores que conozco proporcionan estos tipos, excepto posiblemente cuando están en un modo -pedantic, pero en este caso int64_t o uint64_t no estarán disponibles con los compiladores anteriores a C++ 2011. En todos los sistemas <stdint.h> está disponible, también. Es decir, que yo sepa, no importa mucho cómo deletree el tipo. El objetivo principal de <stdint.h> es proporcionar la mejor coincidencia para un número específico de bits. Si necesita al menos 64 bits pero también desea aprovechar la implementación rápida de dicho tipo, usaría int_least64_t o uint_least64_t de <stdint.h> o <cstdint> (en el caso de este último, los nombres están definidos en el espacio de nombres std).

+0

Me gustaría que el estándar agregara un tipo más grande como 128 o más, considerando que en este día donde se usa mucho la criptografía, se necesita ese tipo para que no tenga que confía en muchas bibliotecas. – farmdve

+0

No he visto una propuesta para ese tipo ("long long long"?) Aunque soy consciente de que muchos sistemas realmente admiten tipos de 128 bits a través del soporte SIMD: ¡envíe una propuesta a WG14 y/o WG21! –

+2

'long long long' no es necesario; un sistema que admite enteros de 128 bits puede definir * tipos enteros extendidos * y definir 'int128_t' y' uint128_t' en términos de esos tipos. –

23

es la sugerencia general a utilizar int64_t en lugar de long long, cuando la portabilidad es un objetivo importante?

Estaría muy sorprendido si un compilador ofreció int64_t pero no long long.

Si long long está presente, debe tener al menos 64 bits, por lo que la conversión de (u)int64_t a (unsigned) long long conserva el valor.

Si necesita un tipo con exactamente 64 bits, utilizan (u)int64_t, si es necesario, al menos, 64 bits (unsigned) long long está perfectamente bien, como sería (u)int_least64_t.