【问题标题】:Why is <inttypes.h>'s PRIx16 not equal to "hx"?为什么 <inttypes.h> 的 PRIx16 不等于“hx”?
【发布时间】:2017-10-23 23:50:23
【问题描述】:

为什么PRIx16 == "x" in C(和in C++)在 GCC 之下?

我希望它是"hx",以便以下工作:

#include <inttypes.h>

int16_t v = -1;
printf("%04" PRIx16 "\n", v);  // prints ffffffff, not ffff

【问题讨论】:

  • PRIx16 用于uint16_t;你在滥用它。
  • 另一方面,hx 同时适用于signed shortunsigned short,因此这似乎是不必要的限制。 int16_t 是否存在另一个宏?
  • C99 第 7.8.1 章,无符号类型的 PRIx 宏。
  • 我同意 needlessly restrictive,但我不认为 PRIx16 == "x" 不合规。
  • @Eric,你用的是什么版本的standard library

标签: c printf


【解决方案1】:

简答:

要打印签名类型,请使用di

要打印无符号类型,请使用xuo


int16_t v 是一个有符号整数类型。

PRIxNPRIx16 一样被列为“无符号整数的 fprintf 宏”。 PRIxN 未列出“用于有符号整数的 fprintf 宏”。 @Kerrek SB

要将v 打印为十进制文本,请使用PRId16PRIi16

printf("%04" PRId16 "\n", v);

要将v 打印为十六进制文本,请转换/转换为一些无符号。

printf("%04" PRIx16 "\n", (uint16_t)v);

我也希望 "hx" 用于 PRIx16,这就是我的 GCC 编译(GNU C11 (GCC) 版本 6.4.0)的方式,但这更可能是 standard library version 问题(我的:ldd (cygwin ) 2.9.0)。我怀疑 OP 的编译器/库的最新性。

#include <stdio.h>
#include <inttypes.h>

int main(void) {
  printf(PRIx16);
  return 0;
}

输出

hx

【讨论】:

  • 不需要演员表。 OP 的问题与有符号/无符号位解释问题没有任何关系。 “x”不符合规范,应该是“hx”。
  • @jwdonahue 我同意 "hx" 会更好,但 C 规范不支持 "x" 不兼容。与@Hans Passant cmets 一样,有符号类型没有PRIx 宏。因此 OP 的代码是 UB。
  • 与类型无关。查看函数签名:int printf(char*, ...)。无论您推送 int16_t 还是 uint16_t,它都会将两个字节推送到堆栈上。格式字符串由代码解释,假设您实际上对它撒了谎,而不是将 char* 一直向下推。
  • @jwdonahue 您的评论是 "hx" 工作的一个很好的理由(由于整数提升肯定会推送 4 个字节),但它没有解决使用 "x" 的 OP 代码的有效性。 C 指定 PRIx16uint16_t 一起使用,"x" 与它一起使用。 C 没有指定PRIx16 可以与int16_t 一起使用 - 因此它与int16_t 一起使用是UB,即使它适用于某些平台。
  • 我要补充一点,PRIx16 是一个宏,这里没有进行类型检查,它甚至不需要任何参数来检查它们。请编辑您的答案。
猜你喜欢
  • 2019-02-28
  • 2017-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
相关资源
最近更新 更多