繁体   English   中英

当我混合有符号和无符号类型时会发生什么?

[英]what happens when i mix signed and unsigned types ?

我正在学习C ++语言,我对类型转换有一些疑问,你能解释一下像这样的表达式会发生什么:

unsigned int u = 10; 
int a = -42; 
std::cout << u - a << std::endl;

在这里我知道如果我在有两个数学运算符时应用规则,结果将是52.但我想知道当编译器将a转换为无符号值时会发生什么情况会产生一个临时的无符号类型,之后会发生什么? 表达式现在应该是10 -4294967254。

简单来说,如果混合相同等级的类型(在intlong intlong long int的序列中),则无符号类型“wins”,并且在该无符号类型内执行计算。 结果是相同的无符号类型。

如果您混合不同等级的类型,则排名较高的类型“获胜”,如果它可以表示较低等级类型的所有值。 计算在该类型内执行。 结果是那种类型。

最后,如果排名较高的类型不能表示较低排名类型的所有值,则使用较高排序类型的无符号版本。 结果是那种类型。

在您的情况下,您混合了相同等级的类型( intunsigned int ),这意味着整个表达式在unsigned int类型中求值。 正如你所说的那样,表达式现在是10 - 4294967254 (对于32位int )。 无符号类型遵循模运算规则,以2^324294967296 )作为模数。 如果仔细计算结果(可以算术地表示为10 - 4294967254 + 4294967296 ),它将变为预期的52

1)由于标准的促销规则, signed类型a在减法之前被提升为unsigned类型。 根据此规则(C ++标准4.7 / 2)进行促销:

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2n,其中n是用于表示无符号类型的位数)。

代数上a变成一个非常大的正数,肯定比u

2) u - a是匿名临时的,将是无符号类型。 (您可以通过编写auto t = u - a并在调试器中检查t的类型来验证这一点。)数学上这将是一个负数,但在隐式转换为无符号类型时,将调用类似于上面的环绕规则。

简而言之,两个转换操作具有相同和相反的效果,结果将是52.实际上,编译器可能会优化所有这些转换。

这里是反汇编代码说:

它首先将-42设置为其补码并执行子操作。 所以结果是10 + 42 0x0000000000400835 <+8>: movl $0xa,-0xc(%rbp) 0x000000000040083c <+15>: movl $0xffffffd6,-0x8(%rbp) 0x0000000000400843 <+22>: mov -0x8(%rbp),%eax 0x0000000000400846 <+25>: mov -0xc(%rbp),%edx 0x0000000000400849 <+28>: sub %eax,%edx 0x000000000040084b <+30>: mov %edx,%eax

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM