J'ai ce qui suit
size_t i = 0;
uint32_t k = 0;
printf("i [ %lu ] k [ %u ]\n", i, k);
J'obtiens l'avertissement suivant lors de la compilation:
format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’
Quand j'ai exécuté ceci en utilisant une 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,
uint32_t
de<stdint.h>
ou<inttypes.h>
; si vous souhaitez utiliser ces types, vous devez mettre à niveau vers C89. En tant qu'extension, il est probable que GCC vous autorise à les utiliser, mais C89 ne disposait pas d'un tel support.size_t
est «z», comme dans"%zu"
.uint32_t
, mais elle manquesize_t
. La réponse de @ u0b34a0f6ae comprend les deux.Réponses:
On dirait que vous vous attendez
size_t
à être le même queunsigned long
(peut-être 64 bits) alors qu'il s'agit en fait d'ununsigned int
(32 bits). Essayez d'utiliser%zu
dans les deux cas.Je ne suis pas tout à fait sûr cependant.
la source
int32_t
qu'il se trouve qu'il se trouveint
sur votre compilateur / plateforme que cela peut ne pas êtrelong
sur un autre. Pareil poursize_t
. En fait, il fait tout son possible et fait plus de travail pour détecter ce bogue de portabilité, car la vérification facile et naturelle serait simplement d'honorer le typedef comme le fait le compilateur.%lu
avec(unsigned long)k
est toujours correct.size_t
est plus compliqué, c'est pourquoi a%zu
été ajouté dans C99. Si vous ne pouvez pas l'utiliser, traitez-le commek
(long
c'est le plus gros type de C89, ilsize_t
est très peu probable qu'il soit plus grand).Essayer
Le
z
représente un entier de même longueur quesize_t
, et laPRIu32
macro, définie dans l'en-tête C99inttypes.h
, représente un entier 32 bits non signé.la source
printf( "%lu", (unsigned long )i )
. Sinon, on se retrouve plus tard avec une pile d'avertissements partout dans le code en raison d'un changement de type.uint32_t
donc en fait c'est du code C99, et devrait être compilé comme tel.Tout ce dont vous avez besoin est que les spécificateurs de format et les types concordent, et vous pouvez toujours effectuer un cast pour que cela soit vrai.
long
est au moins 32 bits, donc%lu
avec(unsigned long)k
est toujours correct:size_t
est plus compliqué, c'est pourquoi a%zu
été ajouté dans C99. Si vous ne pouvez pas l'utiliser, traitez-la commek
(long
c'est le plus gros type de C89, ilsize_t
est très peu probable qu'il soit plus grand).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 hors du tableau. Tant que vous utilisez des casts explicites pour faire correspondre les types, c'est portable.la source
Si vous ne souhaitez pas utiliser les macros PRI *, une autre approche pour imprimer N'IMPORTE QUEL type entier consiste à convertir en
intmax_t
ouuintmax_t
et à utiliser"%jd"
ou%ju
, respectivement. Ceci est particulièrement utile pour les types POSIX (ou d'autres OS) qui n'ont pas de macros PRI * définies, par exempleoff_t
.la source