打印char时会发生哪些整体促销活动?

lee*_*e77 10 c printf variadic-functions undefined-behavior integer-promotion

我最近读过这篇文章

unsigned char x=1;
printf("%u",x);
Run Code Online (Sandbox Code Playgroud)

由于格式说明符%u,因此调用未定义的行为,printf需要unsigned int.但我还是想了解这个例子中发生了什么.

我认为整数推广规则适用于表达式printf("%u",x) 和由...表示的值x.

A.6.1整体推广

无论是否有符号,都可以使用字符,短整数或整数位字段,或者枚举类型的对象,可以在任何可以使用整数的表达式中使用.如果int可以表示原始类型的所有值,则该值将转换为int; 否则该值将转换为unsigned int.这个过程称为整体推广.

"可以使用"是什么意思?这是否意味着"在句法上是正确的"还是"定义的行为"?

在这个例子中如何推广x?我已经读过它被提升为一个int,但是如果printf("%u", (int x))仍然是未定义的行为那么我真的不明白为什么......

Eri*_*hil 4

由于printf使用变量参数列表,因此整数提升将应用于其整数参数。在任何正常的 C 实现中,整数提升会将 an 转换unsigned char为 an int。然后您正在格式化intWith 的说明符unsigned int,因此行为未定义。

说可以使用整数的地方可以使用字符与您的语句具有 C 标准未定义的行为这一事实之间并不存在冲突。尽管您可以使用字符代替整数,但有关打印内容的规则%u仍然适用。如果使用字符产生适合说明符的整数,则定义行为。如果使用字符导致整数不适合说明符,则 C 标准未定义该行为。

Stack Overflow 上其他地方的讨论得出的结论是,一种奇异的 C 实现理论上可能符合 C 标准,同时具有与类型char一样宽的类型(普通、有符号和无符号)int。在这样的实现中, 和int无法代表 an 的所有值unsigned char,因此unsigned char必须将 an 提升为 an unsigned int。然而,这样的实现会很奇怪并且很麻烦(特别是在处理 EOF 时),并且您在实践中可能会忽略它。