tags:

views:

103

answers:

3

Hello,

gcc 4.4.4 c89 -Wall -Wextra

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,

Steve

+2  A: 

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 %u in both cases.

I'm not entirely certain though.

Cogwheel - Matthew Orlando
No warnings when compiling. However, running splint I get the following: 1) printf (%u) expects unsigned int gets uint32_t: i 2) printf (%u) expects unsigned int gets size_t: k
robUK
Sounds like splint is just being pedantic, then. It's probably going off the names of types in the source code and doesn't realize they're equivalent. I wonder what it would do with @KennyTM's answer... It certainly should be more portable.
Cogwheel - Matthew Orlando
splint is actually doing the right thing. Just because `int32_t` happens to be `int` on your compiler/platform doesn't mean it might not be `long` on another. Same for `size_t`. It's actually going out of its way and doing **more** work to detect this portability bug since the easy, natural check would be to just honor the typedef like the compiler does.
R..
+6  A: 

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.

KennyTM
Compiles with no warnings. But splint doesn't like it. Unrecognized format code: %zu. And for the second one. Parse Error. (For help on parse errors, see splint -help parseerrors.)*** Cannot continue.
robUK
@robUK: Heh. I suggest you file a bug for splint.
KennyTM
This is the right answer. Though my personal recommendation is to simply cast, e.g. `printf( "%lu", (unsigned long )i )`. Otherwise one ends up later with pile of warnings all over the code due to a type change.
Dummy00001
This is the correct answer. I agree with KennyTM about filing a bug for splint.By the way, "%zu" is the proper format for size_t. You don't need any of the PRI* macros for printing size_t.
R..
+1  A: 

If you don't want to use the PRI* macros, another approach for printing ANY integer type is to cast to intmax_t or uintmax_t and use "%jd" or %ju, respectively. This is especially useful for POSIX (or other OS) types that don't have PRI* macros defined, for instance off_t.

R..