对于以下代码,我会溢出,但可悲的是,我似乎无法理解原因。
std::int8_t smallValue = -1;
unsigned int value = 500;
std::uint8_t anotherSmallValue = 1;
auto test = smallValue * value * anotherSmallValue;
然后
test
是一个相当大的值。有人可以解释,这是怎么回事?
最佳答案
当编译器看到smallValue * value
时,给定输入数据类型signed
(8位)和unsigned int
(通常为16或32位),编译器必须决定结果的数据类型是什么。 C++规则指出,在这种情况下,结果将是未签名的。因此,smallValue * value
的值不能为-500
,正如您所期望的那样。而是将-500
值解释为一个正数。
此外,您在此处将8位值乘以通常为16位或32位的值。在这种情况下,C++的规则规定,较小的存储值将首先转换为与较大的存储值相同的大小;因此,在这种情况下,smallValue * value
的结果确实足够大,可以存储一定数量的500
。
继续乘以无符号数量anotherSmallValue
(= 1)将导致另一个unsigned
具有相同的值。
因为您使用的是auto
,所以推论返回类型为unsigned
。
只需简单地转换回signed
(例如,通过将test
值定义为int
而不是auto
,通常可以将整个操作的结果转换回signed
值,而无需内部更改位;这然后将正确显示-500
,如您期望的那样;但是,正如其他张贴者所指出的那样,从理论上讲,这是非常危险的,因为不能保证它可以正常工作,尽管通常可以用今天的编译器来工作。
关于c++ - 奇怪的整数溢出逻辑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15834326/