web-dev-qa-db-fra.com

Spécificateurs de format printf pour uint32_t et size_t

J'ai le suivant

size_t   i = 0;
uint32_t k = 0;

printf("i [ %lu ] k [ %u ]\n", i, k);

Je reçois l'avertissement suivant lors de la compilation:

format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’

Lorsque j'ai utilisé cette attelle, j'ai obtenu ce qui suit:

Format argument 1 to printf (%u) expects unsigned int gets size_t: k

Merci beaucoup pour tout conseil,

90
ant2009

On dirait que vous attendez size_t être identique à unsigned long (peut-être 64 bits) alors qu’il s’agit d’un unsigned int (32 bits). Essayez d'utiliser %zu dans les deux cas.

Je ne suis pas tout à fait certain cependant.

22
Cogwheel

Essayer

#include <inttypes.h>
...

printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);

Le z représente un entier de longueur identique à size_t, et le PRIu32 macro, défini dans l'en-tête C99 inttypes.h , représente un entier non signé de 32 bits.

125
kennytm

Tout ce dont vous avez besoin, c'est que les spécificateurs de format et les types concordent, et vous pouvez toujours utiliser le transtypage pour rendre cela vrai. long est d'au moins 32 bits, donc %lu ensemble avec (unsigned long)k est toujours correct:

uint32_t k;
printf("%lu\n", (unsigned long)k);

size_t est plus compliqué, c'est pourquoi %zu a été ajouté à C99. Si vous ne pouvez pas l'utiliser, alors traitez-le comme k (long est le plus gros type de C89, size_t est très peu probable d'être plus grand).

size_t sz;
printf("%zu\n", sz);  /* C99 version */
printf("%lu\n", (unsigned long)sz);  /* common C89 version */

Si vous n'obtenez pas les spécificateurs de format corrects pour le type que vous passez, alors printf fera l'équivalent de lire trop ou trop peu de mémoire dans le tableau. Tant que vous utilisez des conversions explicites pour faire correspondre des types, il est portable.

23
u0b34a0f6ae

Si vous ne souhaitez pas utiliser les macros PRI *, une autre méthode d'impression ANY est un type entier qui doit être converti en intmax_t ou uintmax_t et utilise "%jd" ou %ju, respectivement. Ceci est particulièrement utile pour les types POSIX (ou autres systèmes d’exploitation) pour lesquels les macros PRI * ne sont pas définies, par exemple off_t.

16
R..