c - 打印字符时会发生哪些积分提升?

标签 c printf undefined-behavior variadic-functions integer-promotion

我最近读到的

unsigned char x=1;
printf("%u",x);

调用未定义的行为,因为格式说明符 %u,printf 需要一个无符号整数。但我仍然想了解这个例子中发生了什么。

我认为积分提升规则适用于表达式 printf("%u",x) 以及 x 表示的值。

A.6.1 Integral Promotion

A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer may be used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion.

这里的“可能被使用”是什么意思?这是否意味着“语法正确”或“定义的行为”?

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

最佳答案

printf使用可变参数列表,整数提升应用于其整数参数。在任何普通的 C 实现中,整数提升转换为 unsigned char。到int .然后你正在格式化 int带有 unsigned int 的说明符,所以行为是未定义的。

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

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

关于c - 打印字符时会发生哪些积分提升?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19444843/

相关文章:

c - 如何计算两个地址之间的距离?

c - 如何打印链表中除最后一个元素之外的每个元素

c - 多重声明中的第二个 int 是否始终设置为 1?

c++ - 是否有任何 2 补码平台/编译器,其中 signed shift 不做通常的事情?

c - (C, pthreads) 让多个线程同步并一起继续

c - “无论如何,遵循 "prefer++i over i++"指南,你就不会出错。” C语言中这背后的原因是什么?

C++11嵌套宏调用?

scanf() 问题之前的 C/C++ printf()

linux - 目录中的占位符 - awk 中的 printf

c - 为什么 char* 会导致未定义的行为,而 char[] 不会?