printf format specifiers for uint32_t and size_t
I have the following
size_t i = 0;
uint32_t k = 0;
printf("i [ %lu ] k [ %u ]\n", i, k);
I get the following warning when compiling:
format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’
When I ran this using splint I got the following:
Format argument 1 to printf (%u) expects unsigned int gets size_t: k
Many thanks for any advice,
Solution 1:
Try
#include <inttypes.h>
...
printf("i [ %zu ] k [ %"PRIu32" ]\n", i, k);
The z
represents an integer of length same as size_t
, and the PRIu32
macro, defined in the C99 header inttypes.h
, represents an unsigned 32-bit integer.
Solution 2:
Sounds like you're expecting size_t
to be the same as unsigned long
(possibly 64 bits) when it's actually an unsigned int
(32 bits). Try using %zu
in both cases.
I'm not entirely certain though.
Solution 3:
All that's needed is that the format specifiers and the types agree, and you can always cast to make that true. long
is at least 32 bits, so %lu
together with (unsigned long)k
is always correct:
uint32_t k;
printf("%lu\n", (unsigned long)k);
size_t
is trickier, which is why %zu
was added in C99. If you can't use that, then treat it just like k
(long
is the biggest type in C89, size_t
is very unlikely to be larger).
size_t sz;
printf("%zu\n", sz); /* C99 version */
printf("%lu\n", (unsigned long)sz); /* common C89 version */
If you don't get the format specifiers correct for the type you are passing, then printf
will do the equivalent of reading too much or too little memory out of the array. As long as you use explicit casts to match up types, it's portable.