vmo*_*eco 7 c standards printf undefined-behavior language-lawyer
每个转换规范由字符%引入.在%之后,以下顺序出现:
- 零个或多个标志[...].
- 可选的最小字段宽度.[...]
- 一个可选的精度,它提供了为s转换写入的最大字节数.精度采用句点(.)后跟[...]可选十进制整数的形式;
- 可选的长度修改器[...].+转换说明符[...].
- 可选的最小字段宽度.[...]
- 转换说明符[...].
后来:
如果省略精度,则采用负精度参数.
printf("%.-1s\n", "foo")根据我如何解释标准定义,我期望得到什么:我从标准中得到的第二个引用表明我们可以传递一个负精度参数,并且这种精度会被忽略.
所以,printf("%.-1s\n", "foo")应该相当于printf("%s\n", "foo"),它会显示"foo\n"和返回4.
printf("%.-1s\n", "foo")我使用的系统(osx)上的实际行为:printf("%.-1s\n", "foo")显示" \n"和返回2.
这显然不同于我的预期.
- 我对标准的解释是否有误?
我认为你的解释可以总结如下:
因此,
printf("%.-1s\n", "foo")应该相当于printf("%s\n", "foo"),它将显示"foo\n"并返回 4。
不。您引用的有关忽略负精度参数的规定不适用于这种情况。该条款讨论的是在格式字符串中指定精度*并将该值作为单独printf参数传递的选项:
printf("%.*s\n", -1, "foo");
Run Code Online (Sandbox Code Playgroud)
在这种情况下,负精度参数会导致printf()其行为就像未指定精度一样。你的情况有所不同。
另一方面,这里的标准并不要求格式字符串中出现的精度值是非负十进制整数。它确实在其他几个地方以这种方式限定术语“十进制整数”,包括同一部分前面的内容,但在有关精度字段的段落中却没有这样做。
- 这种行为是未定义的吗?
不。对所需语义有两种相互冲突的解释(见下文),但无论哪种方式,标准都定义了行为。它可以解释为
当负精度值直接在格式字符串中呈现时,针对负精度参数描述的行为也适用。这样做的优点是一致性,并且这是您报告观察到的行为。然而,
标准的字面解读表明,当精度在格式字符串中表示为负十进制整数时,则应用该部分中描述的普通语义;对于s指令,负精度表示要输出的最大字符数。
您观察到的行为与前一种解释不一致,但考虑到输出少于 0 字节的实际困难,后一种解释未成功实现对我来说并不奇怪。我倾向于猜测后者是您的实现试图实现的。
我怀疑这是在某个阶段的无意遗漏,为精度字段提供了负值的可能性,但无论有意与否,标准似乎都允许这样做。
| 归档时间: |
|
| 查看次数: |
258 次 |
| 最近记录: |