简体   繁体   中英

Is there any case where %p format specifier will not print address in 0x.. format

In C, I am reading an address from console and storing it in a variable. I need to log the address in hex (0x...) format.

I have 2 options:

  1. %p
  2. %x

I have tried option 2 (%x). And it works differently on 32 and 64 bit platforms. This resulted in inaccurate program behavior.

Now second option (%p) is also implementation defined.

So I would like to know which one should be used to have consistent behavior across all compilers and platforms.

The C standard does not guarantee any method of printing pointers is completely “consistent” across all implementations and cannot do so since pointers are inherently specific to memory models, which are not controlled by the C standard.

You can control some aspects of printing a pointer, such as ensuring it is always printed with hexadecimal, by converting it to uintptr_t and using the usual printf conversion controls:

#include <inttypes.h> // Define PRIxPTR.
#include <stdint.h>   // Define uintptr_t.
#include <stdio.h>    // Declare printf.

void PrintPointer(const volatile void *p)
{
    printf("0x%08" PRIxPTR, (uintptr_t) p);
}

This will ensure the pointer is printed using hexadecimal to represent its bits. The uintptr_t must contain sufficient information to reproduce the pointer value (or an equivalent), so the display will necessarily contain sufficient information about the pointer. However, the order and meaning of the bits is not defined by the C standard. The 08 guarantees at least eight digits are printed (with leading zeros as needed), which gives you some uniformity across mixed architectures of 32- and 64-bit pointers, but C implementations could use any number of bits, so a pointer could be printed with more digits. You could use just "0x%" if you do not consider fixing the number of digits to be part of the “consistent” formatting.

The uintptr_t type is optional but is likely to be provided in modern C implementations.

(The const and volatile qualifiers are irrelevant to the routine itself; they are included merely so that pointers with them, or without them, can be passed to the routine without complaint from the compiler.)

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