简体   繁体   English

是否存在 %p 格式说明符不会以 0x.. 格式打印地址的情况

[英]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.在 C 中,我正在从控制台读取地址并将其存储在变量中。 I need to log the address in hex (0x...) format.我需要以十六进制(0x ...)格式记录地址。

I have 2 options:我有两个选择:

  1. %p %p
  2. %x %X

I have tried option 2 (%x).我已经尝试过选项 2 (%x)。 And it works differently on 32 and 64 bit platforms.它在 32 位和 64 位平台上的工作方式不同。 This resulted in inaccurate program behavior.这导致程序行为不准确。

Now second option (%p) is also implementation defined.现在第二个选项 (%p) 也是实现定义的。

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. C 标准不保证任何打印指针的方法在所有实现中都是完全“一致的”,并且不能这样做,因为指针固有地特定于 memory 模型,这些模型不受 Z0D61F8370CAD11D412F5D70B4E 标准控制。

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:您可以通过将指针转换为uintptr_t并使用通常的printf转换控件来控制打印指针的某些方面,例如确保始终以十六进制打印:

#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. uintptr_t必须包含足够的信息来重现指针值(或等价物),因此显示必须包含有关指针的足够信息。 However, the order and meaning of the bits is not defined by the C standard.但是,C 标准没有定义位的顺序和含义。 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. 08保证打印至少八位数字(根据需要使用前导零),这使您在 32 位和 64 位指针的混合架构中具有一定的一致性,但是 C 实现可以使用任意数量的位,因此可以打印指针有更多的数字。 You could use just "0x%" if you do not consider fixing the number of digits to be part of the “consistent” formatting.如果您不考虑将位数固定为“一致”格式的一部分,则可以只使用"0x%"

The uintptr_t type is optional but is likely to be provided in modern C implementations. uintptr_t类型是可选的,但很可能在现代 C 实现中提供。

(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.) constvolatile限定符与例程本身无关;它们被包含在内只是为了使带有或不带有它们的指针可以传递给例程而不会引起编译器的抱怨。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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