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

C++ 如果我递减'std::size_t(0)`是否保证等于'std::size_t(-1)`?,c++,undefined-behavior,integer-overflow,unsigned-integer,C++,Undefined Behavior,Integer Overflow,Unsigned Integer,以下证据表明: 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; }

以下证据表明:

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\u迭代器
,但我现在真正的问题是,我期望的行为是否定义良好?

是的
size\t
是未指定的无符号整数

C++中所有无符号整数都被建模为整数2n的整数,对于某些n个整数,它是非符号整数类型的。 当您将有符号整数转换为无符号整数时,您将得到该无符号类型的常数n的整数环中模2n的值。对于-1,这是2n-1

如果将0作为无符号整数类型递减,则得到2n-1

这两个值是相同的

从C++标准看[Basic,Basic ] 3.91/4:

无符号整数应遵守算术模定律 2n 哪里 N 是值中的位数 表示特定大小的整数

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


寻找从有符号整数转换如何工作的引号将涉及更多的标准追踪;但它最终是你想要的。

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

是无符号整数类型:

无符号整数算术始终以2n模执行 其中n是该特定整数中的位数

具体考虑到内置的:

[T] 表达式
--x
完全等同于
x-=1

[T] 表达式
x--
修改其操作数的值,就像通过计算
x-=1


因此减量运算符确实执行算术运算。

相关:,@Justin这些是关于无符号整数溢出的,而不是这里发生的下溢。我迄今为止发现的最好的重复:怎么办?您得到了绿色检查,因为有关递增运算符和减量运算符的详细信息。