C 什么才是“真正的”呢;无效的转换规范";?
根据C 什么才是“真正的”呢;无效的转换规范";?,c,printf,language-lawyer,conversion-specifier,C,Printf,Language Lawyer,Conversion Specifier,根据C11,第§7.21.6.1章,第9页 如果转换规范无效,则行为未定义。282)如果任何参数无效 对应转换规范的类型不正确,行为为 未定义 直到那时,我的理解是 char str [] = "Sourav"; 类似于printf(“%S”,str)的语句属于第一句,不存在CS as%S(大写) 类似于printf(“%d”,str)的语句属于第二个句子(CS和参数类型不匹配,但是%d不是无效的CS) 通过最近的评论帖子 我的理解错了吗?第二条语句是否也可以归类为“无效”(PS-非“
C11
,第§7.21.6.1章,第9页
如果转换规范无效,则行为未定义。282)如果任何参数无效
对应转换规范的类型不正确,行为为
未定义
直到那时,我的理解是
char str [] = "Sourav";
- 类似于printf(“%S”,str)的语句属于第一句,不存在CS as
(大写)%S
- 类似于printf(“%d”,str)的语句属于第二个句子(CS和参数类型不匹配,但是
不是无效的CS)%d
更新:答案和注释线程被删除,因为转换规范的“有效性”由您引用的标准段落上方的标准段落决定: 每个转换规范都由字符%引入。在%之后,将依次显示以下内容: 旗帜字符及其含义为: 转换说明符及其含义是: 这意味着,由上述列表中的元素组成的任何转换规范都是有效的,其他所有规范都不在本标准的范围内。这就是为什么代码中的段落提到了UB的两个原因。一个是不符合语法的规范,另一个是规范和类型不匹配 你链接到的评论似乎使用了“无效”的口语。也就是说,转换规范的两种用途都是“无效的”,因为它们会导致UB。但从语言律师的角度来看,只有第一个是“无效的”。为了支持我的理解(可能是为了首先解释理解),让我加上我的两分钱 一分钟,让我们看看脚注282,如引用中所述。上面说, 参见“未来图书馆方向”(7.31.11) 以及§7.31.11 可以在中的转换说明符和长度修饰符中添加小写字母
fprintf
和fscanf
。扩展名中可以使用其他字符
它没有提到CS和它的参数(如果有的话)之间的关系。因此,CS的“有效性”不依赖于提供的参数
现在,也就是说,还有几个指针
- 第1点::请注意引用中提到的短语“转换规范”不是转换规范。根据第§7.21.6.1/P4章
每个转换规范都由字符
引入。在%
之后 按顺序出现:%
- 零个或多个标志[…]
- 可选的最小字段宽度[…]
- 可选精度[…]
- 可选的长度修改器[…]
- 转换说明符字符[…]
- P5,字段宽度和精度
- P6,旗帜
- P7,长度修改器
- P8,转换说明符
- 第2点::另一方面,规范非常清楚CS和提供的相应参数类型之间的“不匹配”。所以,这是一个完全不同的情况
printf("%D", str);
在问题之后。脚注282指出: fprintf和fscanf中的转换说明符和长度修饰符中可以添加小写字母。扩展名中可以使用其他字符 因此,它也暗示了无效的转换说明符意味着那些不在列表中的转换规范,其中小写字母可能会被未来的C版本使用;分机可以自由使用其他字母
虽然不规范,但包含以下内容:
- 在其中一个格式化输入/输出函数或
或strftime
函数的格式中发现无效的转换规范(7.21.6.1、7.21.6.2、7.27.3.5、7.29.2.1、7.29.2.2、7.29.5.1)李>wcsftime
*printf
的无效转换规范与strftime
的无效转换规范成对出现,该转换规范不采用可变参数,且无效性不会因转换规范与相应参数之间的不匹配而产生
这可以与
- 调用其中一个格式化输入/输出函数时,没有足够的格式化参数,或者某个参数的类型不合适(7.21.6.1、7.21.6.2、7.29.2.1、7.29.2.2)
它讨论了参数和转换说明符之间的不匹配,但没有提到“无效”一词。这里到底有什么不清楚的地方?@tilz0R,正如我所说的…“除非另有建议”。如果您可以看到针对此讨论的复制,请标记它。我是jus