C++ 为什么对无符号字符的算术运算会将它们提升为有符号整数?
许多对类似问题的回答指出,这是因为标准。但是,我无法理解标准制定者做出这一决定背后的原因 据我所知,C++ 为什么对无符号字符的算术运算会将它们提升为有符号整数?,c++,c,C++,C,许多对类似问题的回答指出,这是因为标准。但是,我无法理解标准制定者做出这一决定背后的原因 据我所知,无符号字符不以2的补码形式存储值。因此,我没有看到这样一种情况,比如说,XOR对两个无符号字符进行赋值会产生意外的行为。因此,将它们升级到int似乎是在浪费空间(在大多数情况下)和CPU周期 此外,为什么int?如果一个变量被声明为无符号,显然无符号对程序员很重要,因此在我看来,提升为无符号整数仍然比整数更有意义 [编辑#1]如评论中所述,如果int不能充分容纳无符号字符中的值,将升级到无符号in
无符号字符
不以2的补码形式存储值。因此,我没有看到这样一种情况,比如说,XOR对两个无符号字符
进行赋值会产生意外的行为。因此,将它们升级到int
似乎是在浪费空间(在大多数情况下)和CPU周期
此外,为什么int
?如果一个变量被声明为无符号
,显然无符号对程序员很重要,因此在我看来,提升为无符号整数
仍然比整数
更有意义
[编辑#1]如评论中所述,如果int
不能充分容纳无符号字符中的值,将升级到无符号int
[编辑#2]为了澄清这个问题,如果是关于在int
而不是char
上操作的性能优势,那么为什么会出现在标准中?这本可以作为编译器设计者更好优化的建议。现在,如果有人设计了一个不这样做的编译器,这将使他们的编译器不完全遵守C/C++标准,即使假设这个编译器支持该语言的所有其他必需特性。简而言之,我无法找出无法直接在无符号字符
上操作的原因,因此将其升级为整数
的要求似乎是不必要的。你能给我举个例子证明这是错误的吗?你可以在网上找到这份文件:
第6.3章(第44-45页)是关于转换的
在K&R的发布和C89的开发之间,整数提升规则的发展在实现之间出现了严重的分歧。实现分为两大阵营,其特点可能是无符号保留和值保留
这些方法之间的差异主要集中在处理无符号字符
和无符号短字符
时,整数升迁会扩大,但该决定也会影响常量的类型(见§6.4.4.1)
无符号保留方法要求将两个较小的无符号类型提升为unsigned int
。这是一个简单的规则,并生成一个独立于执行环境的类型
如果这些类型可以正确地表示原始类型的所有值,则值保留方法要求将这些类型提升为有符号int
,否则要求将这些类型提升为无符号int
因此,如果执行环境将short
表示为小于int
,则无符号short
变为int
;否则它将变为无符号int
。这两种方案在绝大多数情况下都给出了相同的答案,并且在使用two的补码算法和有符号溢出上的静默环绕的实现中,这两种方案在更多的情况下都给出了相同的有效结果——也就是说,在大多数当前的实现中。在此类实现中,只有当这两个条件均为真时,才会出现两者之间的差异:
包含无符号字符
或无符号短字符
的表达式会产生一个int
范围的结果,在该结果中设置符号位,即,对此类类型执行一元运算,或执行另一个操作数为int
或“更窄”类型的二元运算
上述表达式的结果用于其符号显著的上下文:
•sizeof(int)
并且必须将其扩展为long类型,或者
•在将移位定义为算术移位的实现中,它是右移位运算符的左操作数,或
•它是/、%、=的操作数之一
在这种情况下,真正意义上的解释就会产生歧义。结果必须被称为有疑问的签名,因为签名或未签名的解释都有可能。当一个无符号int
在一个操作符中遇到一个有符号int
,并且有符号int
有一个负值时,就会产生完全相同的歧义。在解决这场对峙的模糊性方面,这两个方案都没有做得更好,也没有做得更糟。突然间,负的有符号整数
变成了一个非常大的无符号整数
,这可能令人惊讶,也可能正是一个知识渊博的程序员想要的。当然,明智地使用类型转换可以避免所有这些歧义
探索这个问题的一个重要结果是理解高质量的编译器可以很好地查找此类有问题的代码并提供(可选)诊断,而认真的指导者可以很好地警告程序员隐式类型转换的问题
无符号保留规则大大增加了unsigned int
与signed int
冲突的情况的数量,以产生一个有符号的结果,而值保留规则将这种冲突最小化。因此,对于新手或粗心的程序员来说,保值规则被认为是更安全的。经过多次讨论,C89委员会决定支持保留值规则,尽管UNIX C编译器已经朝着无符号保留的方向发展
C89的悄然变化
依赖于unsig的程序