对于以下代码,我会溢出,但可悲的是,我似乎无法理解原因。

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/

10-09 13:36