【发布时间】:2017-11-22 03:54:04
【问题描述】:
根据the standards:
每个转换规范都由字符 % 引入。后 %,以下依次出现:
- 零个或多个标志 [...]。
- 可选的最小字段宽度。 [...]
- 一个可选精度,为 [...] s 转换写入的最大字节数。精度采用句点 (.) 后跟 [...] 可选十进制整数的形式;
- 可选的长度修饰符 [...]。 + 转换说明符字符 [...]。
- 可选的最小字段宽度。 [...]
- 转换说明符字符 [...]。
稍后:
采用负精度参数,就好像精度是 省略。
根据我对标准定义的解释,我对 printf("%.-1s\n", "foo") 的期望:
我从标准中引用的第二句话表明我们可以传递一个负精度参数,并且这种精度将被忽略。
所以,printf("%.-1s\n", "foo") 应该等价于 printf("%s\n", "foo"),这将显示 "foo\n" 并返回 4。
然而,这是我使用的系统 (osx) 上的实际 printf("%.-1s\n", "foo") 行为:
printf("%.-1s\n", "foo") 显示 " \n" 并返回 2。
这显然与我的预期不同。
- 难道我对标准的解释有误吗?
- 此行为是否未定义?
- 实际上是否可以传递负精度(编辑:不带星号)?
【问题讨论】:
-
我认为关于否定论点的部分只是在谈论使用
*从参数中获取值的情况,而不是将精度放入格式字符串中。 -
您省略了 7.21.6.1p5 的相关部分:“如上所述,字段宽度或精度或两者都可以用星号表示。在这种情况下,int 参数提供字段宽度或精度。......负字段宽度参数被视为 - 标志,后跟正字段宽度。负精度参数被视为好像省略了精度。所以关于负值的部分显然与传递的参数有关,而不是字符串本身的小数。阅读标准时,所有字词都很重要!
-
@vmonteco:再说一遍:“十进制整数”不包括符号!这甚至没有意义,这就是为什么明确提到参数字段宽度无效的原因(因为不能使负值无效)。
-
@Olaf 该标准在几个地方提到了“十进制整数”、“非负十进制整数”和“有符号十进制整数”。所以看起来可能有“否定”和“签名”。
-
@Olaf 我确实阅读了这条评论,但恕我直言,这并不明显,因为 - 正如 Eugene 所说 - 一些整数字段被定义为“非负数”。
标签: c printf language-lawyer standards undefined-behavior