如果我递减 `std::size_t(0)` 是否保证等于 `std::size_t(-1)`?

If I decrement `std::size_t(0)` is that guaranteed to be equal to `std::size_t(-1)`?

证据如下:

inline
constexpr std::size_t prev(std::size_t i) {
    --i;
    return i;
}

int main() {
    static const std::size_t i = 0;
    static_assert(prev(i) == std::size_t(-1), "Decrementing should give     std::size_t(-1)");    
    return 0;
}

-std=c++14 编译愉快。

我发现这个是因为我在 std::vector 上有一个循环索引并且想向后循环,所以我将其更改为

for (std::size_t i = std::min(idx, v.size() - 1); i != std::size_t(-1); --i) { ... }

现在,我意识到我可以使用 std::vector::reverse_iterator,但我现在真正的问题是,我期望的行为是否定义明确?

size_t 是一个未指定的无符号整数。

C++ 中的所有无符号整数都被建模为整数环的元素模 2n 对于特定于该无符号整数类型的某些数字 n。

当您将有符号整数转换为无符号整数时,您会得到整数环中该无符号类型常量 n 模 2n 的值。对于 -1,这是 2n-1.

当你将 0 作为无符号整数类型递减时,你得到 2n-1.

这两个值相同。

参见 C++ 标准中的 [basic.fundamental] 3.9.1/4:

Unsigned integers shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.

(引用自最近的标准草案 N3690,但它所代表的事实不会很快改变;段落编号可能会改变。)

查找有关从有符号整数转换的工作原理的引用将涉及更多标准追逐;但它最终会成为你想要的。

是的,这种行为是有保证的。

std::size_t is an unsigned integer type. Arithmetic on unsigned integers always has well defined semantics:

Unsigned integer arithmetic is always performed modulo 2n where n is the number of bits in that particular integer.

特别考虑内置 pre-decrement and post-decrement operators:

[T]he expression --x is exactly equivalent to x -= 1. ...
[T]he expression x-- modifies the value of its operand as if by evaluating x -= 1

所以减量运算符确实执行算术运算。