c++ - %p 的 printf 格式说明符标志 '0',正确与否?

标签 c++ printf gcc-warning

将“0”作为标志附加到 printf %p 格式说明符是否正确?

#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 的警告:

“警告:‘0’标志与‘%p’gnu_printf 格式 [-Wformat] 一起使用”

cppreference printf 读取,我看到了:

0 : for integer and floating point number conversions, leading zeros are used to pad the field instead of space characters. For integer numbers it is ignored if the precision is explicitly specified. For other conversions using this flag results in undefined behavior. It is ignored if - flag is present.

据我所知,%p 是指针地址,它毕竟是一个整数,那么这种未定义的行为是否适用于 %p?
如果不是,为什么会出现 GCC -Wformat 警告?

最佳答案

%p is for pointer address, which is an integer number after all

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

您可以通过 using uintptr_t data type 解决此问题,将您的指针转换为它,然后将其打印为无符号整数:

#include <cinttypes>
#include <cstdint>

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

Demo.

关于c++ - %p 的 printf 格式说明符标志 '0',正确与否?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42416839/

相关文章:

c - printf() - 如何添加前导零 + 填充

c - printf 的意外输出

32bit-64bit - 我在 32 位架构中的 gcc 编译中有以下警告,但在 64 位架构中没有任何此类警告

c++ - 我怎样才能告诉 gcc 在不中断的情况下对 switch/case 语句发出警告(或失败)?

c++ - 即使在析构函数之后,我是否必须手动删除对象?

c++ - lambda 可以有外部 "C"链接吗?

java - 用c++编写的电话应用程序

c - 如何使用变量设置以 fprintf '%s' 格式输出的字符数?

c++ - 修复 GCC 中的 "comparison is always false ..."警告

c++ - 如何在函数中更改对象C++的值