为什么负 size_t 下溢但减去它没有?

问题描述

我这里有一个简单的程序,它返回 18446744073709551615:

#include <iostream>

using namespace std;

int main()
{
    cout<<-(size_t)1;
    cout<<0-(size_t)1;
    return 0;
}

另外,我这里也有这个程序,它返回预期的结果 0:

#include <iostream>

using namespace std;

int main()
{
    cout<<1-(size_t)1;
    return 0;
}

有人可以向我解释这里发生了什么吗?如果 -(size_t)10-(size_t)1 下溢,为什么 1-(size_t)1 没问题?

解决方法

为什么 1-(size_t)1 没问题?

因为它不会溢出。 1可表示为std::size_t,减法结果为0也可表示。

所以不应该 -(size_t)1 评估为大数

正如您在第一个示例中使用一元减号运算符时所发现的那样。但是您没有在第二个示例中使用一元减号运算符。您使用了二元减号运算符。

那么会变成1+大数吗?

减法不会“变成”加法。

也就是说,您会发现 1 + std::size_t(-1) 也是 0。这是因为无符号算术是模数。 -1 与某个大值一致,而大值 + 1 与 0 一致。模算术的这种特性被称为“与翻译的兼容性”