2010-12-10 15 views
5

consideran este código:Printf con typedef enteros, especialmente 64bit

typedef int64_t Blkno; 
#define BLKNO_FMT "%lld" 
printf(BLKNO_FMT, (Blkno)some_blkno); 

Esto funciona bien y muy bien en x86. En x64, int64_t es en realidad un long, en lugar de un long long, y mientras long y long long son del mismo tamaño en x64, el compilador genera un error:

src/cpfs/bitmap.c:14: warning: format ‘%lld’ expects type ‘long long int’, but argument 6 has type ‘Blkno’

  1. ¿Cómo puedo saber que estoy printf pasando un tipo de 64 bits?
  2. ¿Existe alguna forma mejor de estandarizar las especificaciones para los tipos de usuario que usando un #define como BLKNO_FMT como se indica anteriormente?

Respuesta

10

Use PRId64 de inttypes.h.

Blkno no es un nombre de tipo muy bueno. BLKNO_FMT podría reemplazarse por PRIdBLKNO.

#include <inttypes.h> 
#include <stdio.h> 

typedef int64_t Blkno; 
#define PRIdBLKNO PRId64 

int main(void) { 
    printf("%" PRIdBLKNO "\n", (Blkno)1234567890); 
    return 0; 
} 
+0

El molde '(Blkno)' no tiene sentido si ha utilizado el especificador de formato correcto. – user502515

+3

No es inútil, los argumentos enteros a funciones variadas no se promueven a largo plazo. – dreamlax

+0

@ user502515: Sin '(Blkno)' el compilador produce ''advertencia: conversión especifica tipo' largo 'pero el argumento tiene tipo' int '[-Wformat]'' – jfs

0

Estos tipos no son de 64 bits. Son específicos de la plataforma. La única forma portátil de imprimirlos es emitir a intmax_t o uintmax_t y usar los especificadores de formato correctos para imprimir esos tipos.

+1

Parece que está equivocado esta vez @R .. :) –

+1

De hecho, asumí que OP estaba trabajando con los tipos relacionados con el sistema de archivos POSIX. Si OP definió el tipo para ser de 64 bits, por supuesto, es de 64 bits .. :-) –