简体   繁体   中英

using %x to print the hex address contained in a pointer

i just read this short article http://karwin.blogspot.com/2012/11/c-pointers-explained-really.html which describes pointers really well. The author however says that the addresses are just these hex values, so he prints it with %x, but when i do this not only do i get a warning from the compiler saying i am passing a pointer instead of an unsigned int, but sometimes i get something that doesn't resemble an address at all (like 1C). Can somebody clarify the issue please?

%x expects its corresponding argument to have type unsigned int , which is why you get the warning and funky output. Use %p to display pointer values:

T *p = some_pointer_value;
...
printf( "p = %p\n", (void *) p );

%p expects its corresponding argument to have type void * . This is pretty much the only place you should explicitly cast a pointer to void * in C.

Edit

Just looked at the page. Be aware, that code sample is old (written ca. 1990) and uses K&R-style (pre-1989 standard) function definition syntax and implicit int all over the place. It's using %x to display pointer values because the %p conversion specifier wasn't added to the language until the 1989 standard.

It should not be used as a model of modern C programming practice.

His explanation of pointers is pretty decent, though.

%x is used to print a value in hex. While pointers are usually written in hex, there are other considerations for pointers that make %x a bad fit, like that 1C output you saw.

%p is meant for pointers, and is probably what you're looking for. It will format the pointer a bit better, since it knows that it's a pointer.

1C is a perfectly valid hex output, but it's odd for a pointer, since you expect certain special things to happen when displaying pointers, like having the correct length.

Since %x is meant for hex numbers, passing a pointer into it will give you a warning. One reason it gives you the warning is that pointers aren't necessarily the same size as an unsigned int.

%x expects an unsigned int , passing anything else is UB .

For printing a data-pointer, there is %p which can print void-pointers (type void* , the conversion is not optional), which will normally print it with hexadecimal notation.

If that's not satisfying you, consider casting the pointer to uintptr_t and printing that using the format-specifier-macros PRIxPTR or PRIXPTR from <inttypes.h> , for guaranteed hexadecimal output.
You even get to select the case used.

Values cannot be "hex". Values are just values. Meanwhile, "hex" is a way to represent values for human consumption. "Hex" is a notation.

Using %x directly on pointers is illegal though, since %x format specifier expects an unsigned int argument, not a pointer. A pointer can be cast to unsigned int type, and the result can be used with %x format specifier, but this will not work in general case since unsigned int type can easily be too narrow to properly represent the numerical address value.

In other words, forget about %x . It is hopelessly useless in that application. The author of your article is doing it very wrongly.

If you really want to print a pointer p through its conversion to integral type, the proper way to go would be this

printf("%" PRIxPTR "\n", (uintptr_t) p);

Note the use of uintptr_t type and PRIxPTR macro that stands for an implementation-defined format specifier associated with that type.

Other than that you can use a dedicated format specifier %p , which prints void * pointers and typically uses hex notation for that purpose.

Pointers if manipulated with the intergral formats like %x or %u give undefined results. %p is recommended for pointers. As far as the warning is concerned, %x expects an unsigned int, and your variable has probably different size or alignment requirement than unsigned int so you are getting the warning.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM