Plataformas independientes size_t Especificadores de formato en c?

86

Quiero imprimir una variable de tipo size_ten C, pero parece que size_ttiene un alias para diferentes tipos de variables en diferentes arquitecturas. Por ejemplo, en una máquina (64 bits), el siguiente código no genera ninguna advertencia:

size_t size = 1;
printf("the size is %ld", size);

pero en mi otra máquina (32 bits), el código anterior produce el siguiente mensaje de advertencia:

advertencia: el formato '% ld' espera el tipo 'long int *', pero el argumento 3 tiene el tipo 'size_t *'

Sospecho que esto se debe a la diferencia en el tamaño del puntero, por lo que en mi máquina de 64 bits size_ttiene un alias a long int( "%ld"), mientras que en mi máquina de 32 bits size_ttiene un alias de otro tipo.

¿Existe un especificador de formato específicamente para size_t?

Ethan Heilman
fuente
Su mensaje de advertencia no coincide con el código. La advertencia menciona punteros, su código no tiene ninguno. ¿Sacaste algo de &alguna parte?
Jens
Punteros? No, no recibo ninguna advertencia sobre los punteros, de hecho, dependiendo de la máquina en la que ejecuto ese código, a veces no recibo ninguna advertencia. Pruebe el siguiente código de prueba: #include <stdio.h> int main () {size_t size = 1; printf ("el tamaño es% ld", tamaño); return 0; }
Ethan Heilman
1
@EthanHeilman Se está refiriendo al hecho de que sus advertencias dicen warning: format '%ld' expects type 'long int *', but argument 3 has type 'size_t *'cuándo probablemente debería decirse warning: format '%ld' expects type 'long int', but argument 3 has type 'size_t'. ¿Quizás estaba usando en su scanf()lugar cuando recibió estas advertencias?
RastaJedi

Respuestas:

123

Sí: use el zmodificador de longitud:

size_t size = sizeof(char);
printf("the size is %zu\n", size);  // decimal size_t ("u" for unsigned)
printf("the size is %zx\n", size);  // hex size_t

Los otros modificadores de longitud que están disponibles son hh(para char), h(para short), l(para long), ll(para long long), j(para intmax_t), t(para ptrdiff_t) y L(para long double). Ver §7.19.6.1 (7) del estándar C99.

Adam Rosenfield
fuente
¿Cuál es la diferencia entre zd y zu? Entiendo que zd es decimal, pero ¿está firmado? Si es así, ¿cómo afecta zd las cosas?
Ethan Heilman
1
Es la diferencia entre ay size_tan ssize_t; este último rara vez se utiliza.
Adam Rosenfield
26
Bien, entonces en este caso, debería usar %zu, porque el argumento no está firmado.
caf
Las otras opciones disponibles se explican en la página del manual de printf: linux.die.net/man/3/printf
INS
9
@detly: No, el zmodificador de longitud no forma parte de C89 / C90. Si está apuntando a un código compatible con C89, lo mejor que puede hacer es enviar unsigned longy usar el lmodificador de longitud, por ejemplo printf("the size is %lu\n", (unsigned long)size);; El soporte tanto de C89 como de sistemas con size_tmayor tamaño longes más complicado y requeriría el uso de una serie de macros de preprocesador.
Adam Rosenfield
45

Sí hay. Lo es %zu(como se especifica en ANSI C99).

size_t size = 1;
printf("the size is %zu", size);

Tenga en cuenta que size_tno tiene signo, por lo que %ldes doblemente incorrecto: modificador de longitud incorrecto y especificador de conversión de formato incorrecto. En caso de que se lo pregunte, %zdes para ssize_t(que está firmado).

maxschlepzig
fuente
1

MSDN , dice que Visual Studio admite el prefijo "I" para código portátil en plataformas de 32 y 64 bits.

size_t size = 10;
printf("size is %Iu", size);
Arkantos
fuente
6
es específico de MS, que no cumple con los estándares, por lo que no es independiente de la plataforma
phuclv
@phuclv De hecho. Y si realmente dice, como sugiere la respuesta, "portátil", es incluso peor de lo que nunca supe sobre la EM. No es que me sorprendería ... No soy de los que votan negativamente porque alguien hizo el esfuerzo de intentar responder algo, pero aún así esta respuesta es simplemente incorrecta. Ah, creo que entiendo la idea aquí en 'portátil'. Debe decirse que funciona tanto para 32 bits como para 64 bits. Pero por supuesto que lo haría.
Pryftan