什么是“无效的转化规范”?

时间:2017-08-09 10:41:53

标签: c printf language-lawyer conversion-specifier

根据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}}。

3 个答案:

答案 0 :(得分:9)

"有效性"转换规范由您引用的标准段落确定:

7.21.6.1 - p4 to p8

  

每个转换规范都由字符%引入。在%之后,以下顺序出现:...

     

旗帜字符及其含义是:......

     

转换说明符及其含义为:...

这意味着由上述列表中的元素组成的任何转换规范都是有效的,所有其他转换规范都不在标准的视野中。这就是为什么代码中的段落提到了UB的两个原因。一个是不符合语法的规范,另一个是规范和类型不匹配。

您链接的评论似乎使用"无效"通俗。即转换规范的使用都是"无效",因为它们导致UB。但只有第一个是"无效"从语言律师的角度来看。

答案 1 :(得分:1)

为了支持我的理解(并且可能首先要理解理解),让我加上我的两分钱。

如上所述,让我们看一下脚注282。它说,

  

参见“未来图书馆方向”(7.31.11)。

和§7.31.11

  

可以将小写字母添加到转换说明符和长度修饰符中   fprintffscanf。其他字符可用于扩展名。

其中没有提及CS与其参数(如果有的话)之间的关系。因此,CS的“有效性”不依赖于提供的参数。

现在,那说了几个指针

  • 第1点::请注意在报价中提及“转换规范”,不是转换说明符。根据章节§7.21.6.1/ P4,

      

    每个转换规范都由字符%引入。在%之后,以下内容   按顺序出现:

         
        
    • 零个或多个标志[...]

    •   
    • 可选的最小字段宽度[...]

    •   
    • 可选的精度[...]

    •   
    • 可选的长度修饰符[...]

    •   
    • 转化说明符字符[...]

    •   

    我们有

    中提到的所有元素的权威列表
    • P5,字段宽度和精度
    • P6,flags
    • P7,长度修饰符
    • P8,转换说明符

    因此,与提供的参数存在(或应该)无关,以识别转换规范的“有效性”。

    为了补充这种理解,借用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.包含以下内容:

  
      
  • 在其中一个格式化输入/输出函数或strftimewcsftime函数的格式中找到了无效的转换规范(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)。
  •   

讨论了参数和转换说明符之间的不匹配,但未提及无效。