为什么在 C++ 中混合 size_t 和 unsigned int 时模除法会出错

laz*_*boy 5 c++ static-cast

给定一个程序

#include <iostream>
using namespace std;

int main()
{
     const size_t DoW = 7;
     const unsigned int DAYS_OF_WEEK = static_cast<unsigned int> (DoW);
     unsigned int dayOfFirstDay = 0;
     unsigned int _firstDayOfWeek = 1;
     unsigned int diff = (DAYS_OF_WEEK+ (dayOfFirstDay - _firstDayOfWeek) ) % DAYS_OF_WEEK;
     cout << "diff = ("  << DAYS_OF_WEEK << " + (" << dayOfFirstDay << " - " << _firstDayOfWeek << ")) %" << DAYS_OF_WEEK
         << " = " << diff << endl;
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是

diff = (7 + (0 - 1)) %7 = 6
Run Code Online (Sandbox Code Playgroud)

这是预期的。但是修改后的程序没有static_cast

diff = (7 + (0 - 1)) %7 = 6
Run Code Online (Sandbox Code Playgroud)

产出

diff = (7 + (0 - 1)) %7 = 3
Run Code Online (Sandbox Code Playgroud)

这是意料之中的。为什么?

(两个程序都是g++在 64 位 Ubuntu 上用9.3.0编译的)

rus*_*tyx 4

看来你的平台size_t是64位的,而且unsigned int是32位的。

没有整体升级到 64 位1。这就是在表达式中混合 64 位操作数的危险。

因此,当转换为 64 位时,32 位环绕 -1 仍为 4294967295。

我们得到 7 + 4294967295(以 64 位执行)= 4294967302(无环绕)。

4294967302 % 7 = 3


1unsigned ( )本身为 64 位的系统除外int,目前这种情况不太可能发生。