带有短整数编译器警告的 Printf

Printf with short integer compiler warning

#include <stdio.h>

int main(void)
{
  short i = 1;

  printf("%hd\n", i);
  printf("%hd\n", i * i);
  return 0;
}

编译它会给出警告 warning: format specifies type 'short' but the argument has type 'int' [-Wformat] printf("%hd\n", i * i);

删除 printf("%hd\n", i * i); 语句不会产生警告。

我是不是做错了什么?据我了解,由于 i 的类型为 short int,因此表达式 i * i 的值的类型为 short int,但随后 printf 执行整数提升以将其转换为short int 结果为 int 形式,然后再次将此 int 转换为 short(由于转换说明符)。

虽然我没有特别看出代码有什么问题。这只是一个警告,告诉我要小心可能导致比简单的 short int 变量更复杂的表达式作为参数传递给对应于 %hd 转换说明符的 printf 的可能性在溢出?谢谢!

i * i 中,乘法的参数经过 "integer promotions" and "usual arithmetic conversions" 并在乘法完成之前变为 int。乘法的最终结果是一个整数。

i * i的类型为int(当i的类型为intshortchar_Bool).


当您使用 "%hd" 调用 printf 时,相应的参数应该是 short。发生的事情是它自动转换为 int 并且它是 printf 看到的 int 。 printf 的内部代码会将 int 转换为 short 来完成它的工作。
问题是如果您以 short.

范围之外的 int 值开始
short i = SHRT_MAX;
int j = i * i;
short k = i * i; // overflow while assigning
printf("%hd %hd", j, k);
//                ^ (kinda) overflow inside the innards of printf