I have been having problems with using printf from the Pico SDK to print a mix of 32 and 64 bit quantities.
Here is an example:
uint32_t u32 = 1000;
uint64_t u64 = 2000;
int32_t i32 = 3000;
int64_t i64 = 4000;
printf("u32 %u u64 %lu i32 %d i64 %ld\n", u32, u64, i32, i64);
produces:
u32 1000 u64 2000 i32 0 i64 3000
if I make the printf be:
printf("i64 %ld i32 %d u64 %lu u32 %u\n", i64, i32, u64, u32);
it produces
i64 0 i32 4000 u64 0 u32 3000
In each case the third number is incorrectly printed.
It isn't a bug in printf. You're using the wrong length specifier for the 64-bit values. e.g. You've got %ld so it is expecting a 32-bit value but you're giving it a 64-bit value. You need to use %lld instead.
Code:
Select all
printf("u32 %u u64 %llu i32 %d i64 %lld\n", u32, u64, i32, i64);
printf("i64 %lld i32 %d u64 %llu u32 %u\n", i64, i32, u64, u32);
If you give gcc the -Wall argument then it will warn you about any mismatch between the format string and the arguments.
int32_t i32 = 3000;
int64_t i64 = 4000;
printf("u32 %u u64 %lu i32 %d i64 %ld\n", u32, u64, i32, i64);
produces:
u32 1000 u64 2000 i32 0 i64 3000
That's because your printf specifiers don't match with what you are passing.
%ld
says to print a
long
but you are passing a
long long
which would be
%lld
If you
#include <inttypes.h>
then you can use the standard's macros to get the correct specifiers.
Code:
Select all
#include <inttypes.h>
//...
printf("u32 %"PRIu32" u64 %"PRIu64" i32 %"PRIi32" i64 %"PRIi64"\n", u32, u64, i32, i64);
Code: Select all
try.c: In function 'main':
try.c:26:26: warning: format '%lu' expects argument of type 'long unsigned int', but argument 3 has type 'uint64_t' {aka 'long long unsigned int'} [-Wformat=]
26 | printf("u32 %u u64 %lu i32 %d i64 %ld\n", u32, u64, i32, i64);
| ~~^ ~~~
| | |
| long unsigned int uint64_t {aka long long unsigned int}
| %llu
try.c:26:41: warning: format '%ld' expects argument of type 'long int', but argument 5 has type 'int64_t' {aka 'long long int'} [-Wformat=]
26 | printf("u32 %u u64 %lu i32 %d i64 %ld\n", u32, u64, i32, i64);
| ~~^ ~~~
| | |
| long int int64_t {aka long long int}
| %lld