该标准很明确:当对小于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编译器朝着无符号保留的方向发展,但委员会还是决定采用保留值的规则。
(我建议阅读全文。我只是不想在这里引用整个内容。)