2010-10-25 7 views
13

De vez en cuando uso la aritmética de 64 bits en una biblioteca C++ de código abierto. Descubrí que long long sirve mi propósito bastante bien. Incluso una caja de solaris de 10 años podría compilarla. Y funciona sin jugar con #defines en Windows también.Cómo hacer una aritmética portátil de 64 bits, sin advertencias del compilador

Ahora el problema es que recibo quejas de mis usuarios porque compilan con configuraciones antiguas de GCC, y GCC insiste en emitir advertencias de que long long no es parte del estándar de C++. Probablemente esto sea correcto, pero no estoy demasiado interesado en el estándar de C++ per se, solo quiero que mi código funcione en tantos compiladores como sea razonablemente posible.

Así que mi pregunta es doble:

  • Puede alguien nombrar compiladores de C++ reales que no soportan 64 bits de largo de largo?
  • ¿Hay alguna manera de hacer que GCC compile aritmética de 64 bits (en la plataforma de 32 bits) sin advertencias del compilador? (stdint.h no ayuda, ya que también depende de long long)

P.S.

Si hay plataformas donde long longs se convierten en 128 bit o más grandes, eso es interesante, pero no es un problema para mí.

+5

El uso de -pedantic es una buena manera de obtener * no * el trabajo realizado y excluye el uso de la mayoría de las bibliotecas de terceros sin una buena razón. Es lo que dice en la lata: una queja sin sentido, pero no creo que decirles a tus usuarios que dejen de ser tan tontos te atraiga a ellos tampoco. – Clifford

+11

@Clifford: '-pedantic' está ahí para ayudarte a escribir código que será fácil de portar a otros compiladores en el futuro. Si no está preocupado por eso, no tiene que usarlo, pero terminará siendo la persona que está escribiendo todas esas bibliotecas de terceros que (a) producen advertencias extrañas, y (b) posiblemente no lo haga. Trabajar en algunos compiladores. De acuerdo, 'long long' no es el problema real más probable, pero solía trabajar en un producto portátil y varias veces arreglábamos cosas de los chicos de Windows que en realidad no funcionaban en algunas de nuestras plataformas (y gcc -pedantic se los habría dicho así). –

+0

... curiosamente, cuando los programadores de Linux estaban trabajando en el componente portátil del producto, era menos probable que fallaran las pruebas en otras plataformas. –

Respuesta

15

Cuando la biblioteca se proporciona como fuente, una opción es proporcionar una "portar" de cabecera, en el que es responsabilidad de los usuarios para proporcionar un tipo de 64 bits (que le especifique el nombre) . Naturalmente, también es su responsabilidad tratar con las advertencias del compilador que provoque su elección del tipo, ya sea evitarlas, suprimirlas o ignorarlas.

Supongo que esto es lo que llamas "jugar con #defines", pero no creo que haya demasiados errores. Puede proporcionar una versión predeterminada que solo usa long long directamente y funcionará en su caja de Solaris de 10 años y también en Windows, por lo que la mayoría de los usuarios nunca necesitarán acercarse a la parte configurable por el usuario de su biblioteca.

Luego, para los usuarios pedantes, puede proporcionar una versión para GCC que incluye <sys/types.h> y utiliza int64_t en lugar de long long. Esto no provoca ninguna advertencia para mí con g++ -pedantic.Incluso podría hacer esto en la versión predeterminada mediante el reconocimiento de GCC, que sin duda está jugando con #defines, pero de nuevo no de una manera inusual para un producto multiplataforma.

Si su biblioteca también se proporciona como archivos binarios para ciertas plataformas, entonces, por supuesto, debe decidir qué tipo de 64 bits va a ser. Si también aparece en la interfaz de la biblioteca (y, por lo tanto, en el archivo de encabezado), entonces tendrá que elegir uno que no provoque advertencias con opciones de compilación razonables. Creo que -pedantic es una opción de compilación razonable, y al parecer también lo hacen sus usuarios, así que de nuevo es int64_t en GCC.

+0

+1, creo que int64_t es la mejor solución aquí. – rmeador

+0

Tengo una config.h.En algún momento ya estaba usando 'int64_t' (de stdint.h), pero lo abandoné por mucho tiempo porque este último era mucho más amplio. Lo interesante es que 'int64_t' (de stdint.h) funciona, aunque es typedef para' long long' (en mi sistema). Me gana, pero gracias por ponerme en el camino correcto. –

+0

@jdv: Eso es por lo que Void menciona: el encabezado de GCC usa '__extension__', en'/usr/include/sys/_types.h' en mi máquina. –

12

En GCC, use la opción del compilador -Wno-long-long para suprimir esa advertencia en particular.

También podría usar -std=C++0x, pero probablemente reducirá aún más la portabilidad.

+0

Realmente espero que se pueda arreglar sin un interruptor de línea de comando, pero gracias de todos modos. –

4

Puede silenciar la advertencia con -Wno-long-long (asegúrese de que aparezca después de -pedantic). Yo creo que C99 requiere números enteros de 64 bits y creo que también C++ 0x, por lo que los compiladores que no los tienen están siendo raros hoy en día.

+0

No creo que se requiera soporte de 'long long' por C99, pero creo que es requerido por C++ 0x. – Brian

+0

Estoy 100% seguro de que está en C99, pero estoy bastante seguro de que no está en C++ 98. (Era un gran problema en ese momento, porque Microsoft forzó al comité a aceptar "' sizeof (size_t)> sizeof (long) '" como una opción legítima de ABI, que C89 prometió que nunca sucedería). – zwol

+0

Mantendré el argumento acerca de C99 en mente. –

0

Puede reemplazar su uso de long long con una de las muchas librerías C++ bigint. Estoy seguro de que algunos de ellos evitan este error de compilación. Personalmente, prefiero quedarme con el error.

4

También puede suprimir la advertencia usando "__extension__" característica de gcc, por ejemplo:

// No '-pedantic' warning/error. 
__extension__ long long foo = 2; 

// Exhibits '-pedantic' warning/error. 
long long bar = 3 

y la compilación:

$ g++ -pedantic -fsyntax-only foo.cpp 
foo.cpp:5: error: ISO C++ 1998 does not support 'long long' 

en cuenta que sólo el último uso de long long provocó el error -pedantic desde no se agregó __extension__. De todos modos, iría con @Steve Jessop's suggestion de usar int64_t en su lugar.

1

Si tiene Boost en un sistema incluyen directorio, se puede decir

#include "boost/cstdint.hpp" 
boost::int64_t my_64_bit_number; 

Si se trata de un sistema include, advertencias se suprimen automáticamente.

+1

No usaré esta sugerencia, ya que aún no estoy usando boost. Pero gracias. –

Cuestiones relacionadas