我是否正确理解该程序导致UB的标准:
#include <stdio.h>
int main(void)
{
char a = 'A';
printf("%c\n", a);
return 0;
}
当它在 sizeof(int)==1 && CHAR_MIN==0
的系统上执行时?
因为如果 a
是无符号的并且具有与 int
相同的大小 (1),它将被提升为 unsigned int
[ 1] (2),而不是 int
,因为 int
不能表示 char
的所有值。格式说明符 "%c"
需要一个 int
[2],并且在 printf()
中使用错误的符号会导致 UB [3]。
C99 ISO/IEC 9899 的相关引用
[1] 根据 C99 6.3.1.1:2 升级为 int
:
If an
int
can represent all values of the original type, the value is converted to anint
; otherwise, it is converted to anunsigned int
. These are called the integer promotions. All other types are unchanged by the integer promotions.
[2] 格式说明符 "%c"
需要一个 int
参数,C99 7.19.6.1:8 c
:
If no
l
length modifier is present, theint
argument is converted to anunsigned char
, and the resulting character is written.
[3] 在 fprintf()
(3) 中使用错误的类型,包括错误的符号,会导致根据 C99 7.19.6.1:9 的 UB:
... If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
对于 va_arg
宏,给出了具有不同符号的相同类型的异常(exception)情况,但对于 printf()
则没有,并且不要求 printf()
使用 va_arg
(4)。
脚注: (用 (n) 标记)
这意味着
INT_MAX==SCHAR_MAX
,因为char
没有填充。相同的规则适用于
printf()
,请参阅 C99 7.19.6.3:2
最佳答案
程序可以有或没有未定义的行为取决于实现的特征。
例如,执行的程序
int x = 32767;
x++;
(并且在其他方面已明确定义)在 INT_MAX > 32767 的实现上具有明确定义的行为,否则具有未定义的行为。
您的程序:
#include <stdio.h>
int main(void)
{
char a='A';
printf("%c\n",a);
return 0;
}
对于 INT_MAX >= CHAR_MAX
的任何托管实现都有明确定义的行为。在任何此类实现中, 'A'
的值晋升为int
,这就是%c
预计。
如果INT_MAX < CHAR_MAX
(这意味着 char
是无符号的,并且 CHAR_BIT >= 16
), a
的值晋升为unsigned int
。 N1570 7.21.6.1p9:
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
暗示这有未定义的行为。
实际上,(a) 这样的实现很少见,可能不存在(我听说过的 CHAR_BIT > 8
的唯一现有 C 实现是针对 DSPs 的,并且这样的实现很可能是独立的),并且 (b)任何此类实现都可能被设计为优雅地处理此类情况。
关于c - 在 printf 需要 int 的地方给 printf 一个 char 参数是 UB 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63908544/