printf格式说明符标志'0'对%p有效吗?正确吗?

3
在使用 printf 中的 %p 格式说明符时,是否将 '0' 附加为标记是正确的还是错误的?
#include <stdio.h>
int main()
{
    int a = 42;
    void* p = &a;
    printf("Pointer address: %08p", p);
    return 0;
}

同样在Ideone上也有。

编译类似于上述的一些代码时,我从Microsoft Visual C++ 2015中没有得到任何警告或者其他提示,但是从GCC 5.4.0中却收到了一个警告:

"warning: '0' flag used with '%p' gnu_printf format [-Wformat]"

cppreference printf中了解到:

0:对于整数和浮点数转换,使用前导零填充字段而不是空格字符。对于整数数字,如果明确指定了精度,则会被忽略。对于使用此标志的其他转换,结果是未定义的行为。如果存在-标志,则会被忽略。

据我理解,%p用于指针地址,毕竟它是一个整数数字,那么这个未定义的行为是否适用于%p呢?
如果不是,那为什么GCC给出了-Wformat警告?


我猜是因为代码无意义,由于基本语法问题而无法编译?printf("Pointer address: %08p", return 0; 不要在此处输入代码,而应复制/粘贴实际代码或工作示例。 - Lundin
哎呀,没错,我刚刚发现从Ideone复制和粘贴并不像我预期的那样有效,已经进行了编辑。 - roalz
2个回答

4

%p代表指针地址,但从C/C++类型系统的角度来看,指针并不是整数。

严格来说,指针既不是算术类型也不是整数类型,请参见std::is_integralstd::is_arithmetic


4

%p代表指针地址,实际上是一个整数。

尽管指针确实有数字表示,但标准并不认为指针是整数数据类型。因此,使用%08p格式会导致未定义的行为。

您可以通过使用uintptr_t数据类型解决此问题,将指针转换为uintptr_t,然后将其打印为无符号整数即可。

#include <cinttypes>
#include <cstdint>

int main() {
    int i = 123;
    void* p = &i;
    printf("%08" PRIxPTR "\n", (uintptr_t)p);
    return 0;
}

演示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接