printf format string lint warning
我一直在修复古老的代码,这是今天的问题:
1 2
| output_file_status = fprintf ( data_file ,"%03d%08s%+014.2f%06.3f%",
LongValue , CharStarValue , Double1 , Double2 ); |
Lint32 产生:Lint32 导致格式错误的字符串a€?
1) 你们都同意格式字符串不能以 % 符号结尾吗?我不相信独立的 % 有意义。
2) 当我删除尾随 % 或附加一个附加 % 时,我仍然会收到相同的警告。
这是使用 Oracle Pro*C 编译器(因此 CharStarValue 实际上是 (char*)VarChar.arr )。
一块一块地看:
" d" 需要一个 int。 OP 提供一个 LongValue。对于 long,说明符应为 " ld"。
" s" 需要一个指向 char 的指针。 OP 供应 CharStarValue。行。但是说明符中的 "0" 是 %s 的未定义行为。推荐"%8s"
"% 014.2f" 需要一个 double。行。标志\\'\\'、\\'0\\'都可以。
" .3f" 需要一个 double。行。标志\\'\\'、\\'0\\'都可以。
"%" 后面应该有一些东西,否则行为是未定义的。建议删除或"%%"。
给OP的2分
1 正确的格式不应以单独的 % 结尾,而可以以成对的 %% 结尾。
独立的 % 引入"如果转换规范无效,则行为未定义" C11 7.21.6.1 9.
2 要消除所有警告,请尝试 "%03ld%8s%+014.2f%06.3f".
-
谢谢你的详细解释。我也不确定 s,并感谢您包含的参考资料。
-
@frododot C11 7.21.6.1 6 "标志字符及其含义是: - ... ... 空格 ... # ... 0 对于 d, i, o, u, x, X, a, A, e、E、f、F、g 和 G 转换,前导零(在符号或底数的任何指示之后)用于填充字段宽度而不是执行空格填充,除非在转换无穷大或 NaN 时。如果 0和 - 标志都出现,0 标志被忽略。对于 d、i、o、u、x 和 X 转换,如果指定了精度,则 0 标志被忽略。对于其他转换,行为未定义。
是的,你说得对,最后的 % 本身就是一个错误。在格式化输出中生成一个文字 % 应该是 %%。
可能是您的 linter 也抱怨将 %03d 与 long 值一起使用。那应该是 %03ld.
- 谢谢格雷格,很好的收获。我不认为 32 位编译关心这一点(与 64 位相比)。我会试一试。
-
@frododot:32 位与 64 位无关。格式字符串必须匹配参数的类型,而不仅仅是它的大小。 (如果类型不匹配但大小匹配,您可能会侥幸逃脱,但仍然不正确。)
-
同意重要的是类型,但是在 32 位上,sizeof long == sizeof int,所以 lint 没有抱怨。将 " d" 更改为 " ld" 不会影响 lint\\ 的警告。我确实删除了终止的 \\'%\\',因为这确实很麻烦 :-)