C how to print address as a decimal value (not hex) without compiler warnings

Viewed 297

I have an int pointer that points at the address of another int.

When printing the pointer with the format specifier %p (as suggested by many answers on Stack Overflow), it's printed with a hexadecimal representation.

How can I print a pointer's value with with a decimal representation?


Code Sample

I have figured out one can maybe use %zu from this answer.

int i = 1;
int *p = &i;
printf("Printing p: %%p = %p, %%zu = %zu\n", p, p);

When I run that code using https://onlinegdb.com/EBienCIJnm

  • It actually prints the correct value in decimal
  • But it also outputs a compiler warning
warning: format ‘%zu’ expects argument of type ‘size_t’, but argument 3 has type ‘int *’ [-Wformat=]                                                                 
Printing p: %p = 0x7ffee623d8c4, %zu = 140732759529668

Is there a way to printf a pointer's value with a decimal representation, without compiler warnings?

2 Answers

Convert to the uintptr_t type defined in <stdint.h> and format with the PRIuPTR specifier defined in <inttypes.h>:

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("%" PRIuPTR "\n", (uintptr_t) &argc);
}

Cast the pointer to uintmax_t (defined in <stdint.h>), and print the cast result with %ju:

printf("Printing p: %%p = %p, %%ju = %ju\n", p, (uintmax_t)p);

Note that there is no guarantee that uintmax_t is wide enough to hold a pointer, but it's probably OK. (If it's not OK for your platform, the compiler might complain.) You could use uintptr_t, as suggested elsewhere, but in the case that uintmax_t isn't wide enough, uintptr_t won't exist at all.

On the whole, you're better off learning how to deal with hexadecimal output :-)

Related