Alex Rivera | Logout

Correct format specifier to print pointer or address?

Asked 2012-01-29T13:49:58.273
281

Which format specifier should I be using to print the address of a variable? I am confused between the below lot.

%u - unsigned integer

%x - hexadecimal value

%p - void pointer

Which would be the optimum format to print an address?

Edit
Report

2 Answers

332

The simplest answer, assuming you don't mind the vagaries and variations in format between different platforms, is the standard %p notation.

The C99 standard (ISO/IEC 9899:1999) says in §7.19.6.1 ¶8:

p The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

(In C11 — ISO/IEC 9899:2011 — the information is in §7.21.6.1 ¶8.)

On some platforms, that will include a leading 0x and on others it won't, and the letters could be in lower-case or upper-case, and the C standard doesn't even define that it shall be hexadecimal output though I know of no implementation where it is not.

It is somewhat open to debate whether you should explicitly convert the pointers with a (void *) cast. It is being explicit, which is usually good (so it is what I do), and the standard says 'the argument shall be a pointer to void'. On most machines, you would get away with omitting an explicit cast. However, it would matter on a machine where the bit representation of a char * address for a given memory location is different from the 'anything else pointer' address for the same memory location. This would be a word-addressed, instead of byte-addressed, machine. Such machines are not common (probably not available) these days, but the first machine I worked on after university was one such (ICL Perq).

If you aren't happy with the implementation-defined behaviour of %p, then use C99 <inttypes.h> and uintptr_t instead:

printf("0x%" PRIXPTR "\n", (uintptr_t)your_pointer);

This allows you to fine-tune the representation to suit yourself. I chose to have the hex digits in upper-case so that the number is uniformly the same height and the cha

answered 2012-01-29T14:16:24.317
40

Use %p, for "pointer", and don't use anything else*. You aren't guaranteed by the standard that you are allowed to treat a pointer like any particular type of integer, so you'd actually get undefined behaviour with the integral formats. (For instance, %u expects an unsigned int, but what if void* has a different size or alignment requirement than unsigned int?)

*) [See Jonathan's fine answer!] Alternatively to %p, you can use pointer-specific macros from <inttypes.h>, added in C99.

All object pointers are implicitly convertible to void* in C, but in order to pass the pointer as a variadic argument, you have to cast it explicitly (since arbitrary object pointers are only convertible, but not identical to void pointers):

printf("x lives at %p.\n", (void*)&x);
answered 2012-01-29T13:52:14.100

Your Answer