【发布时间】:2022-01-20 12:36:12
【问题描述】:
标准很明确:当对小于int的整数类型执行算术运算时,整数首先被提升为有符号int,除非int不能代表原始类型的全部值范围,在在这种情况下,促销将改为unsigned int。
我的问题是:这个政策的动机是什么?为什么将无符号类型提升为有符号 int,而不是始终提升为 unsigned int?
当然,实际上几乎没有区别,因为底层汇编指令是相同的(只是零扩展名),但是升级到 signed int 有一个关键的缺点,没有明显的优点,因为溢出是 UB在有符号算术中,但在无符号算术中定义良好。
选择签名int 是否有历史原因?是否存在不使用二进制补码算法的架构,其中将小型无符号类型提升为有符号 int 而不是 unsigned int 更容易/更快?
编辑:我认为这很明显,但我在这里寻找事实(即解释设计决策的一些文档或参考资料),而不是“主要基于意见”的推测。
【问题讨论】:
-
减法可能会产生有符号值? “基本” int 类型已签名?
-
我一直觉得 C 的有符号与无符号规则有点奇怪。例如,在比较有符号整数和无符号整数时,它会执行无符号比较,这对我来说似乎是错误的。所以
-1 < (unsigned) 0产生0。当然,不管你走哪条路,总会有范围的问题,除非你推广到更大的尺寸。但是,是的,在增加大小时对无符号数量进行签名似乎很奇怪。 -
最初没有指定(K&R 1.st edition)。一些编译器采用了一种方式,错误的行为被标准化了,因为人们显然没有意识到“保值”促销是可移植性的噩梦,而不是理智的“未签名”促销。