Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当printf的相应参数不是short/char时,使用h或hh长度修饰符是否非法?_C_Printf_Language Lawyer_Undefined Behavior_Short - Fatal编程技术网

当printf的相应参数不是short/char时,使用h或hh长度修饰符是否非法?

当printf的相应参数不是short/char时,使用h或hh长度修饰符是否非法?,c,printf,language-lawyer,undefined-behavior,short,C,Printf,Language Lawyer,Undefined Behavior,Short,printf函数族提供了一系列长度修饰符,其中两个是hh(表示有符号字符或无符号字符参数提升为int)和h(表示提升为int的signed short或unsigned short参数)。历史上,这些长度修饰符的引入只是为了与scanf的长度修饰符对称,很少用于printf 以下是ISO 9899:2011§7.21.6.1“fprintf功能”7的摘录: 7长度修饰符及其含义为: hh指定以下转换说明符应用于有符号字符或无符号字符参数(参数将根据整数升迁进行升迁,但其值应在打印前转换为有符号

printf
函数族提供了一系列长度修饰符,其中两个是
hh
(表示
有符号字符
无符号字符
参数提升为
int
)和
h
(表示提升为
int
signed short
unsigned short
参数)。历史上,这些长度修饰符的引入只是为了与
scanf
的长度修饰符对称,很少用于
printf

以下是ISO 9899:2011§7.21.6.1“fprintf功能”7的摘录:

7长度修饰符及其含义为:

  • hh
    指定以下转换说明符应用于
    有符号字符
    无符号字符
    参数(参数将根据整数升迁进行升迁,但其值应在打印前转换为
    有符号字符
    无符号字符
    );或者以下
    n
    转换说明符应用于指向有符号字符的指针 争论

  • h
    指定下列
    d
    i
    o
    u
    x
    x
    转换说明符应用于
    短int
    无符号短int
    参数(参数将根据整数提升进行提升,但其值应在打印前转换为
    short int
    无符号short int
    );或者以下
    n
    转换说明符应用于指向short
    int
    参数的指针

忽略
n
转换说明符的情况,这些几乎相同的段落如何描述
h
hh
的行为

  • 在中,有人声称,对于带有
    h
    hh
    长度修饰符的转换规范,传递超出
    有符号字符
    无符号字符
    、或
    无符号短字符
    范围的参数是未定义的行为,因为参数未转换分别从类型
    char
    short
    等开始
  • 我声明该函数以定义良好的方式对
    int
    类型的每个值进行操作,
    printf
    的行为就好像参数在转换之前分别被转换为
    char
    short
  • 还可以说,在默认参数提升之前,使用不属于相应类型的参数调用函数是未定义的行为,但这似乎很难理解

§7.21.6.1¨7(如果有的话)的这三种解释中,哪一种是正确的?

本标准规定:

如果任何参数不是相应转换规范的正确类型,则行为未定义

[C2011 7.21.6.1/9]

“正确类型”的含义可以理解,但对我来说最合理的解释是转换规范“适用于”的类型如同一节前面所述,以及问题中部分引用的。我认为关于论点提升的附加评论是承认普通论点通过规则,并避免将这些功能作为特殊情况的任何含义。我不认为附加评论与确定参数的“正确类型”

如果你传递了一个比转换规范正确的更宽类型的参数,那么实际会发生什么呢?这是一个不同的问题。我倾向于相信C系统不太可能被任何人实现,以至于它会影响a
printf()
参数实际上是一个
char
,或者它是否是一个
int
,其值是否在
char
范围内。但是,我断言,编译器检查参数类型与格式的对应关系并在不匹配时拒绝程序是有效的行为(因为在这种情况下所需的行为没有明确定义)


另一方面,我可以肯定地想象
printf()
实现实际上是不正常的(打印垃圾、损坏内存、吃午餐)如果参数的值超出了相应转换说明符所暗示的范围。由于行为未定义,这也是允许的。

我提出了第一个主张(请参见链接答案)。我确实认为,如果我们对段落中使用的词语过于迂腐,我的主张就站得住脚(升级前的论据是一个
简短的
变体),但这一段/C的精神使得
fuzzxl
的说法更有可能。我认为第一种方法是正确的。转换例程很可能期望有限的范围,因此使用优化的版本(只需考虑8位或16位CPU)。不确定输入参数是否必须是同一类型。问题是,格式字符串解析器如何判断“true”"
int
short
/等转换为
int
的输入参数。另一个方面可能是编译器的内联。在最坏的情况下,它可能会抑制优化,但没有其他功能,因为它必须具有相同的行为。此行有点不清楚-
%h……但它的值应在转换之前转换为short int或unsigned short int int(ore打印)
。那么这是否意味着它可以保存大于
无符号short int/short int
的值,因为它经历了整数升级?如果是,那么它保存的值将转换回其原始变量类型?结果会是什么?如果是