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?
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
The simplest answer, assuming you don’t mind the vagaries and variations in format between different platforms, is the standard
%pnotation.The C99 standard (ISO/IEC 9899:1999) says in §7.19.6.1 ¶8:
(In C11 — ISO/IEC 9899:2011 — the information is in §7.21.6.1 ¶8.)
On some platforms, that will include a leading
0xand 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 tovoid‘. On most machines, you would get away with omitting an explicit cast. However, it would matter on a machine where the bit representation of achar *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>anduintptr_tinstead: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 characteristic dip at the start of
0xA1B2CDEFappears thus, not like0xa1b2cdefwhich dips up and down along the number too. Your choice though, within very broad limits. The(uintptr_t)cast is unambiguously recommended by GCC when it can read the format string at compile time. I think it is correct to request the cast, though I’m sure there are some who would ignore the warning and get away with it most of the time.Kerrek asks in the comments:
I was under the illusion that the C standard says that all object pointers must be the same size, so
void *andint *cannot be different sizes. However, what I think is the relevant section of the C99 standard is not so emphatic (though I don’t know of an implementation where what I suggested is true is actually false):(C11 says exactly the same in the section §6.2.5, ¶28, and footnote 48.)
So, all pointers to structures must be the same size as each other, and must share the same alignment requirements, even though the structures the pointers point at may have different alignment requirements. Similarly for unions. Character pointers and void pointers must have the same size and alignment requirements. Pointers to variations on
int(meaningunsigned intandsigned int) must have the same size and alignment requirements as each other; similarly for other types. But the C standard doesn’t formally say thatsizeof(int *) == sizeof(void *). Oh well, SO is good for making you inspect your assumptions.The C standard definitively does not require function pointers to be the same size as object pointers. That was necessary not to break the different memory models on DOS-like systems. There you could have 16-bit data pointers but 32-bit function pointers, or vice versa. This is why the C standard does not mandate that function pointers can be converted to object pointers and vice versa.
Fortunately (for programmers targetting POSIX), POSIX steps into the breach and does mandate that function pointers and data pointers are the same size:
So, it does seem that explicit casts to
void *are strongly advisable for maximum reliability in the code when passing a pointer to a variadic function such asprintf(). On POSIX systems, it is safe to cast a function pointer to a void pointer for printing. On other systems, it is not necessarily safe to do that, nor is it necessarily safe to pass pointers other thanvoid *without a cast.