在printf需要一个int的情况下,是否要给printf一个char参数的UB?

问题描述

我是否正确理解该程序导致UB的标准:

#include <stdio.h>

int main(void)
{
    char a = 'A';
    printf("%c\n",a);
    return 0;
}

当它在sizeof(int)==1 && CHAR_MIN==0的系统上执行时?

由于a是无符号的,并且大小与({1)}相同(1),因此它将提升为int [1](2),而不是unsigned int,因为int不能代表int的所有值。格式说明符char期望"%c" [2],并且在int中使用错误的符号会导致UB [3]。

C99的ISO / IEC 9899相关报价

[1]根据C99 6.3.1.1:2晋升为printf()

如果int可以代表原始类型的所有值,则该值为 转换为int;否则,它将转换为int。 这些称为整数促销。所有其他类型是 不受整数促销的影响。

[2]格式说明符unsigned int需要一个"%c"参数C99 7.19.6.1:8 int

如果不存在c长度修饰符,则l参数将转换为 int,然后写入结果字符。

[3]在unsigned char(3)中使用错误的类型(包括错误的签名)会导致根据C99 7.19.6.1:9的UB:

...如果任何参数不是对应参数的正确类型 转换规范,其行为是不确定的。

fprintf()宏给出了具有不同符号的相同类型的异常,但va_arg没有给出,并且不要求printf()使用printf()(4)。

脚注: (标记为( n ))

  1. 这意味着va_arg,因为INT_MAX==SCHAR_MAX没有填充。

  2. 另请参阅以下问题:Is unsigned char always promoted to int?

  3. 相同的规则适用于char,请参见C99 7.19.6.3:2

  4. 另请参阅以下问题:Does printf("%x",1) invoke undefined behavior?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)