有人可以用 C++ 解释这个简单程序的输出吗?

问题描述

在我们的代码库中调试问题时,我偶然发现了一个与下面的示例问题非常相似的问题

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v;
    int MAX = 100;
    int result = (v.size() - 1) / MAX;
    std::cout << result << std::endl;
    return 0;
}

我希望程序的输出应该是 0,但它是 -171798692。

有人能帮我理解这个吗?

解决方法

v.size() 返回一个 无符号std::vector::size_type。这通常是 size_t

无符号值中的算术环绕,如果您的 (v.size() - 1) 是 64 位长,则 0xffffffffffffffff 将是 size_t (18446744073709551615)。

将此值除以 100 得出 0x28F5C28F5C28F5C (184467440737095516)。

然后,这个结果被转换为int。如果您的 int 为 32 位长且转换是通过简单截断完成的,则该值将为 0xF5C28F5C

这个值代表 -171798692,它是你得到的,是二进制补码。

,

问题是v.size() - 1

size() 函数返回一个 无符号 值。当您从无符号 1 中减去 0 时,不会得到 -1 而是一个非常大的值。

然后你把这个大的无符号值转换回一个有符号整数类型,它可以把它变成负数。

不仅如此,在 64 位系统上,size() 很可能返回 64 位值,而 int 保持 32 位,这会让您丢失一半数据。

,

向量 v 是空的,所以 v.size() 是 0。而且 v.size() 是无符号的,所以当你从那个 0 减去时会发生奇怪的事情。