2010-03-18 12 views
16

Tengo algún código que está construido tanto en Windows como en Linux. Linux en este punto siempre es de 32 bits, pero Windows tiene 32 y 64 bits. Windows quiere tener time_t ser de 64 bits y Linux todavía lo tiene como 32 bit. Estoy de acuerdo con eso, excepto en algunos lugares los valores de time_t se convierten en cadenas. Entonces, cuando time_T es de 32 bits, debe hacerse con% d y cuando es de 64 bits con% lld ... ¿cuál es la forma inteligente de hacerlo? Además: ¿alguna idea de cómo puedo encontrar todos los lugares donde time_t se pasa a las funciones de estilo printf para abordar este problema?manera portátil de lidiar con 64/32 bit time_t

edición: me ocurrió declarar TT_FMT como "% d" o "% LLD" y luego cambiar mis printfs como en printf ("tiempo:% d, regístrese: bla") para ser printf ("tiempo : "TT_FMT", registra: blah ") ¿Hay una manera mejor? ¿Y cómo los encuentro a todos?

+0

En realidad, creo que desea utilizar especificadores de formato sin firmar. –

+2

Tim, está firmado tanto en Linux como en Windows (ver http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to). De lo contrario, no podría representar toda la vida de Dennis Ritchie. ;) (http://en.wikipedia.org/wiki/Unix_time#Representing_the_number) –

+1

En realidad, time_t también tiene 64 bits de ancho en glibcs ​​contemporáneos para Linux x86_64. – user562374

Respuesta

11

De acuerdo con el estándar C, time_t es un tipo aritmético, "capaz de representar los tiempos". Por lo tanto, podría ser double por ejemplo. (POSIX mentions this more explicitly, y también garantiza que time() devuelve el número de segundos desde la Época — este último no está garantizada por la norma C.)

Tal vez la solución más limpia es convertir el valor a cualquier tipo que desee. Es posible que desee una de unsigned long long o unsigned long:

printf("%llu\n", (unsigned long long)t); 
+0

Esto siempre me ha parecido el método más limpio. Parece una pena que 'printf' no incluyera un especificador de formato para los valores' time_t', incluso si solo fuera el comportamiento '% c' de' strftime'. – caf

+1

Gracias, creo que me gusta, excepto time_t está firmado; Probablemente usaré int64_t. –

7

Creo que la única manera verdaderamente portátil es utilizar strftime para convertir el time_t en una cadena.

Si está seguro de que sólo se está operando en plataformas donde time_t es un int, se podía echar a intmax_t (de stdint.h) e imprimirlo usando PRIdMAX (de inttypes.h).

3

Si desea ir con el especificador de macros, le recomendaría un pequeño ajuste. En lugar de encapsular todo el especificador, encapsular sólo el modificador:

#ifdef 64_BIT_TIME 
    #define TT_MOD "ll" 
#else 
    #define TT_MOD "" 
#endif 

y luego usarlo como esto:

printf("current time in seconds is: %" TT_MOD "u", time(0)); 

La razón es que mientras que usted quiere sobre todo el segundo en decimal, de vez en cuando es posible que desee hexadecimal (o tal vez desee 0 principales). Al tener solo el modificador allí, puede escribir fácilmente:

"%" TT_MOD "x" // in hex 
"%08" TT_MOD "d" // left pad with 0's so the number is at least 8 digits 
+3

Minit nitick; los nombres de macro no pueden comenzar con dígitos. Probablemente vaya por un nombre más parecido al '', sin invadir el espacio de nombres reservado (ISO/IEC 9899: 2011 §7.31.6 _Macros que comienzan con PRI o SCN, y una letra minúscula o X puede ser agregado a las macros definidas en el '' header_). –

Cuestiones relacionadas