【问题标题】:printf format specifier flags '0' for %p, correct or not?printf 格式说明符将 %p 标记为“0”,正确与否?
【发布时间】:2023-03-16 14:25:02
【问题描述】:

将“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 :用于整数和浮点数转换,前导零 用于填充字段而不是空格字符。对于整数 如果明确指定精度,则忽略它。为了 使用此标志的其他转换会导致未定义的行为。它是 如果存在 - 标志,则忽略。

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

【问题讨论】:

  • 我猜是因为代码是无意义的,因为基本语法原因无法编译? printf("Pointer address: %08p", return 0; 不要在此处输入代码,而是复制/粘贴实际代码或工作示例。
  • 天哪,对,我刚刚发现从 Ideone 复制和粘贴无法按预期工作,已编辑。

标签: c++ printf gcc-warning


【解决方案1】:

%p是指针地址,毕竟是整数

虽然指针确实有数字表示,但标准并不认为指针是整数数据类型。因此,使用%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.

【讨论】:

    【解决方案2】:

    %p是指针地址,毕竟是整数,

    不,从 C/C++ 类型系统的角度来看,指针不是整数。

    指针既不是算术也不是整数类型,要学究气,请参阅std::is_integralstd::is_arithmetic

    【讨论】:

      猜你喜欢
      • 2011-05-14
      • 2013-03-14
      • 2017-05-15
      • 2012-05-17
      • 2012-05-17
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      • 1970-01-01
      相关资源
      最近更新 更多