为什么将无符号的“小”整数提升为有符号的int?

use*_*715 6 c standards

该标准很明确:当对小于int的整数类型执行算术运算时,该整数会首先提升为有符号int,除非int不能代表原始类型的完整值范围,在这种情况下,提升为unsigned int

我的问题是:这项政策的动机是什么?为什么将无符号类型提升为有符号类型int,而不是总是unsigned int

当然,实际上,几乎没有什么区别,因为底层的汇编指令是相同的(只是零扩展),但是存在提升为的关键缺点signed int,而没有明显的好处,因为溢出是有符号算术中的UB,但是-用无符号算术定义。

有历史原因更喜欢签字int吗?是否存在不使用二进制补码算法的体系结构,而是将小的无符号类型提升为带符号int而不是unsigned int更容易/更快?

编辑:我认为这很明显,但是我在这里寻找事实(即解释设计决策的一些文档或参考资料),而不是“主要基于意见”的推测。

Kei*_*son 10

这在ANSI C基本原理中得到了解决(链接指向相关部分3.2.1.1)。在某种程度上,它是一个任意选择,可能会发生任何一种变化,但是有做出选择的理由。

自K&R出版以来,在整体晋升规则的发展过程中,C的实现之间已出现严重分歧。实现分为两个主要阵营,其特征可能是未签名的保留价值保留。这些方法之间的区别在于unsigned char 和的处理unsigned short,当通过整数提升将扩展时,和的决定也会对常量的类型产生影响(请参阅第3.1.3.2节)。

无符号保留方法要求促进两个较小的无符号的类型unsigned int。这是一条简单的规则,并产生独立于执行环境的类型。

值保存方法要求促进这些类型 signed int,如果该类型可以正确表示原始类型的所有值,否则为促进这些类型 unsigned int。因此,如果执行环境表示short 小于int,则unsigned short变为int;否则就变成了unsigned int

[SNIP]

未签名的保留规则大大增加了unsigned int面对signed int会产生可疑的签名结果的情况的数量,而价值保留的规则则最大程度地减少了此类冲突。因此,对于新手或不精打细算的程序员,保值规则被认为是更安全的。经过大量讨论,尽管UNIX C编译器朝着无符号保留的方向发展,但委员会还是决定采用保留值的规则。

(我建议阅读全文。我只是不想在这里引用整个内容。)