Well, on your system, pointers obviously are 64 bit. These do not fit into the 32-bit value you cast to, thus you get a warning.
To cast pointers to integers, you should go via uintptr_t
:
printf(" %-10s %08x\n", y, (uint32_t)(uintptr_t)x);
// ^ however, what, if uint32_t is long on your system???
// coming to later...
First cast makes an integer of appropriate size from the pointer, second cast tells the compiler that you explicitly want to truncate the value – and it won't issue a warning any more as it assumes it is what you want to do.
But: You are cutting off the upper half of the address information! If you use this, you might end up in seeing two totally different variables at the same memory location, because the addresses might have differed only in upper half.
You might live with for having shorter logs ('collision' probability shouldn't be too high), the correct way, though, would be outputting via appropriate pointer format specifier %p
:
printf(" %-10s %p\n", y, x); // usually no cast needed, but actually incorrect
printf(" %-10s %p\n", y, (void*)x); // fully compliant variant
This will print all eight bytes (16 nibbles) correctly on your system, four bytes (8 nibbles) on a 32-bit system. If you want to have all eight bytes on any system (for uniform logs), then you can go via appropriate casts again:
printf(" %-10s %016llx\n", y, (uint64_t)x);
// ^ uint64_t most likely is unsigned long long
// but on 64-bit linux, just unsigned long!!!
Casting to uintptr_t
is not necessary this time, as any pointer would fit into – and some time in the future, when the first 128-bit systems appear, you might even want the warning to re-appear (and if really not, add the intermediate cast again). Edit: As denoted, not fixing the warning would result in undefined behaviour, though. So to be on the safe side, you'd rather explicitly catch the issue via static_assert(sizeof(uintptr_t) <= sizeof(uint64_t))
, which would enforce adjustment (thanks, chux, for the hint).
Well, correct format specifier... Luckily, there are appropriate macros defined, although usage is not really nice:
printf(" %-10s %016" PRIx64 "\n", y, (uint64_t)(uintptr_t)x);
(would have been PRIx32
in initial example).