C++ 为什么C++;将表达式中的有符号整数转换为无符号整数?
比较C++ 为什么C++;将表达式中的有符号整数转换为无符号整数?,c++,types,casting,C++,Types,Casting,比较int与无符号int时,例如: signed int si = -1; unsigned int ui = 0; if (ui > si) { // Do something } si将转换为无符号int,因此它将大于ui。那么,如果结果不符合预期,为什么还要这样做呢?这样做是出于历史原因吗?如果他们不得不再次这样做,他们也不会允许这样做?C++有以下规则来决定在整数升级完成后将两个值转换为哪种类型(第5章,第9条): 如果两个操作数的类型相同,则无需进一步转换 否则,如
int
与无符号int
时,例如:
signed int si = -1;
unsigned int ui = 0;
if (ui > si)
{
// Do something
}
si
将转换为无符号int
,因此它将大于ui
。那么,如果结果不符合预期,为什么还要这样做呢?这样做是出于历史原因吗?如果他们不得不再次这样做,他们也不会允许这样做?C++有以下规则来决定在整数升级完成后将两个值转换为哪种类型(第5章,第9条):
- 如果两个操作数的类型相同,则无需进一步转换
- 否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则整数转换秩较小的操作数类型应转换为秩较大的操作数类型
- 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则具有有符号整数类型的操作数应转换为具有无符号整数类型的操作数类型
- 否则,如果有符号整数类型的操作数类型可以表示无符号整数类型的操作数类型的所有值,则无符号整数类型的操作数应转换为有符号整数类型的操作数类型
- 否则,两个操作数都应转换为与带符号整数类型的操作数类型相对应的无符号整数类型
最后一条规则适用于这里,因为
int
和unsigned int
具有相同的等级。原因主要是历史原因。即使在今天,C++也与C代码兼容。您可以采用C代码库,并逐字转换为C++,即使有一些小的差异和不兼容,它也可能会工作。C已经定义了这种方式,C++将不会改变它,因为否则它会改变代码的含义,从而破坏否则会工作的程序。p>
在中,您可以找到第5.10.5节中的规则。此规则之所以存在,是因为它是问题的最佳解决方案 苹果和桔子是无法比较的。唯一的选择是:
- 把橘子换成苹果
- 把苹果换成橙色
- 将两者转换为其他常见类型
long
,然后进行比较。起初这似乎是个好主意,但如果你再仔细考虑一下,就会发现一些问题:
- 如果
和long
的大小相同,那么这实际上没有帮助int
- 即使
大于long
,您也将问题转移到比较int
与long
的情况无符号long
- 编写可移植代码将更加困难
short
和char
升级为int
的历史规则实际上非常烦人,因为它会改变调用哪个重载
我们不想引入任何相同类型的规则(例如,如果与
无符号int
相比,将int
提升为long
,但前提是sizeof(long)
sizeof(int)
yada-yada-yada) 该语言只有两种选择:
- 将已签名的视为未签名的
- 将未签名的视为已签名
归根结底,选择语言是因为它的代码效率更高。这是不应混合使用有符号和无符号的原因之一。我只能假设默认的整数比较运算符按位比较性能,而不是按有符号/无符号值进行比较。这可能是通过这种方式进行性能推理的。我会让一个大师解释一下,因为我也感兴趣。如果C++将一个未签名的int转换成一个已签名的int,那么问题仍然会发生。e、 g.
signed int si=0;unsigned int ui=(unsigned)-1;如果(ui>si){//Do something}
请参阅to question.withclang-Weverything
您将收到一条关于此类比较的警告。但是,如果隐式转换可能导致意外结果,为什么首先允许隐式转换,请执行其他操作(新创建的)编程语言允许这种行为?为什么将两者转换为无符号比将两者转换为有符号更有意义?@BenjaminLindley嗯,转换为有符号会调用实现定义的行为,而转换为无符号则不会。由于转换为签名实际上没有任何其他好处,相比于转换为无符号,这意味着转换为无符号是更好的。@ MaMoudjt1,这只是意外的,如果你没有从一个好的学习参考学习:)C++是强类型的;在查看任何表达式时,请记住每个子表达式的类型,并且还请记住必须在编译时知道该类型。我不是指“意外”,因为我不知道这种行为会发生