What's the proper use of printf to display pointers padded with 0s

后端 未结 9 2042
暖寄归人
暖寄归人 2021-01-31 14:32

In C, I\'d like to use printf to display pointers, and so that they line up properly, I\'d like to pad them with 0s.

My guess was that the proper way to do this was:

相关标签:
9条回答
  • 2021-01-31 15:08

    It's easy to solve if you cast the pointer to a long type. The problem is this won't work on all platforms as it assumes a pointer can fit inside a long, and that a pointer can be displayed in 16 characters (64 bits). This is however true on most platforms.

    so it would become:

    printf("%016lx", (unsigned long) ptr);
    
    0 讨论(0)
  • 2021-01-31 15:09

    This answer is similar to the one given earlier in https://stackoverflow.com/a/1255185/1905491 but also takes the possible widths into account (as outlined by https://stackoverflow.com/a/6904396/1905491 which I did not recognize until my answer was rendered below it ;). The following snipped will print pointers as 8 0-passed hex characters on sane* machines where they can be represented by 32 bits, 16 on 64b and 4 on 16b systems.

    #include <inttypes.h>
    #define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2))
    
    printf("0x%0*" PRIxPTR, PRIxPTR_WIDTH, (uintptr_t)pointer);
    

    Note the usage of the asterisk character to fetch the width by the next argument, which is in C99 (probably before?), but which is quite seldom seen "in the wild". This is way better than using the p conversion because the latter is implementation-defined.

    * The standard allows uintptr_t to be larger than the minimum, but I assume there is no implementation that does not use the minimum.

    0 讨论(0)
  • 2021-01-31 15:11

    #include <inttypes.h>

    #include <stdint.h>

    printf("%016" PRIxPTR "\n", (uintptr_t)ptr);

    but it won't print the pointer in the implementation defined way (says DEAD:BEEF for 8086 segmented mode).

    0 讨论(0)
  • 2021-01-31 15:11

    Note that if the pointer prints with the "0x" prefix, you would need to substitute "%018p" to compensate.

    0 讨论(0)
  • 2021-01-31 15:13

    Use:

    #include <inttypes.h>
    
    printf("0x%016" PRIXPTR "\n", (uintptr_t) pointer);
    

    Or use another variant of the macros from that header.

    Also note that some implementations of printf() print a '0x' in front of the pointer; others do not (and both are correct according to the C standard).

    0 讨论(0)
  • 2021-01-31 15:18

    As your link suggests already, the behaviour is undefined. I don't think there's a portable way of doing this as %p itself depends on the platform you're working on. You could of course just cast the pointer to an int and display it in hex:

    printf("0x%016lx", (unsigned long)ptr);
    
    0 讨论(0)
提交回复
热议问题