根据C11
,章节§7.21.6.1,P9
如果转换规范无效,则行为未定义。 282)如果任何参数是 不是相应转换规范的正确类型,行为是 未定义。
直到时间,我的理解是,
char str [] = "Sourav";
printf("%S", str);
这样的陈述属于第一句话,没有CS作为%S
(大写)printf("%d", str);
之类的语句属于第二句(CS和参数类型不匹配,但%d
不是“无效”CS,无论如何)until advised otherwise最近的评论帖子。
我的理解错了吗?第二个语句也可以被归类为“无效”(PS-而不是“错误”)转换说明符吗?
更新:删除答案和评论主题,{< 10K用户{/ 3}}。
答案 0 :(得分:9)
"有效性"转换规范由您引用的标准段落确定:
每个转换规范都由字符%引入。在%之后,以下顺序出现:...
旗帜字符及其含义是:......
转换说明符及其含义为:...
这意味着由上述列表中的元素组成的任何转换规范都是有效的,所有其他转换规范都不在标准的视野中。这就是为什么代码中的段落提到了UB的两个原因。一个是不符合语法的规范,另一个是规范和类型不匹配。
您链接的评论似乎使用"无效"通俗。即转换规范的使用都是"无效",因为它们导致UB。但只有第一个是"无效"从语言律师的角度来看。
答案 1 :(得分:1)
为了支持我的理解(并且可能首先要理解理解),让我加上我的两分钱。
如上所述,让我们看一下脚注282。它说,
参见“未来图书馆方向”(7.31.11)。
和§7.31.11
可以将小写字母添加到转换说明符和长度修饰符中
fprintf
和fscanf
。其他字符可用于扩展名。
其中没有提及CS与其参数(如果有的话)之间的关系。因此,CS的“有效性”不依赖于提供的参数。
现在,那说了几个指针
第1点::请注意在报价中提及“转换规范”,不是转换说明符。根据章节§7.21.6.1/ P4,
每个转换规范都由字符
%
引入。在%
之后,以下内容 按顺序出现:
零个或多个标志[...]
可选的最小字段宽度[...]
可选的精度[...]
可选的长度修饰符[...]
转化说明符字符[...]
我们有
中提到的所有元素的权威列表因此,与提供的参数存在(或应该)无关,以识别转换规范的“有效性”。
为了补充这种理解,借用comment by Ajay Brahmakshatriya
中的单词“我认为这里的操作词是”对应的。“第一句话说如果在字符串中存在一个无效的说明符。如果不存在,则每个说明符与其对应的参数匹配。然后关于类型匹配的第二个陈述.....我认为第二个例子不在于第一个类别,因为“对应”没有使用“
第2点:: 另一方面,规范与CS和提供的相应参数类型之间的“不匹配”非常明显和清晰。所以,这完全是另一种情况。
现在,例如,在两种情况合并的情况下,很难告诉哪个条件会导致UB,但是出于多种原因,它肯定是UB。
示例:
printf("%D", str);
关注这个问题。
答案 2 :(得分:1)
脚注282指向Future library directions C11 7.31.11p1:
可以将小写字母添加到fprintf和fscanf中的转换说明符和长度修饰符。其他字符可用于扩展名。
所以它也暗示无效的转换说明符表示列表中不的转换规范,其中小写字母可能会被未来的C版本使用;和扩展可以免费使用其他字母。
虽然非规范性,C11 Appendix J.2.包含以下内容:
- 在其中一个格式化输入/输出函数或
strftime
或wcsftime
函数的格式中找到了无效的转换规范(7.21.6.1,7.21.6.2,7.27.3.5,7.29) .2.1,7.29.2.2,7.29.5.1)。
即。 *printf
的无效转换规范与strftime
的无效转换规范配对 - 它不接受变量参数,并且转换规范与相应参数之间的不匹配不会导致无效;
这可以与
形成对比
- 在调用其中一个格式化输入/输出函数时,格式参数不足,或者参数没有合适的类型(7.21.6.1,7.21.6.2,7.29.2.1,7.29.2.2)。
讨论了参数和转换说明符之间的不匹配,但未提及无效。