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