首页 > 解决方案 > 哪些格式字符串允许作为后备?

问题描述

让我们举以下五个例子:

// OK, most correct
printf("%10.4hd XXX", (short) 2);

// OK, no warning
printf("%10.4d XXX", (short) 2);

// Error: [-Werror,-Wformat]
printf("%10.4hhd XXX", (short) 2);

// Error: [-Werror,-Wformat]
printf("%10.4ld XXX", (short) 2);

// Error: [-Werror,-Wformat]
printf("%10.4f XXX", (short) 2);

例如,为什么第二个可以正常工作,而第三个、第四个和第五个却不行?

标签: c

解决方案


在 C 中,表达式(short)2在传递给printf. 这意味着它变成了一个int.

printf提供h长度说明符,但它使用的值将是 a int,而不是 ashort因为在 C 中没有办法将短值直接传递给 var-arg 函数。

来自 ISO/IEC 9899:TC3 第 6.19.6.1.7 节的h长度说明符:

指定后面的 d、i、o、u、x 或 X 转换说明符适用于 short int 或 unsigned short int 参数(该参数将根据整数提升进行提升,但其值应转换为 short int或 unsigned short int 打印前);或者后面的 n 转换说明符适用于指向短 int 参数的指针。

由于%hhd类似的原因,格式字符串也应该起作用。我想 clang 警告这个而不是警告的原因"%d", (short)是后者在技术上是正确的,并且有很多 C 代码使用 %d 来打印短裤。

这可能总是未定义的行为,但在实践中可能会或可能不会工作,%ld具体取决于是否具有相同的表示(通常这将是如果和都是 64 位)。intlongintlong

%f始终是未定义的行为。%f需要一个双参数(不是 a float,因为浮点数在传递给 var-args 函数时总是被提升为double),并且你给它一个int.


推荐阅读