Here's evidence that it is:
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;
}
That compiles happily with -std=c++14.
I came upon this because I had a loop indexing over a std::vector and wanted to loop backward, so I changed it to
for (std::size_t i = std::min(idx, v.size() - 1); i != std::size_t(-1); --i) { ... }
Now, I realize I could use std::vector::reverse_iterator, but my real question now is, is the behavior I'm expecting well-defined?
size_t is an unspecified unsigned integer.
All unsigned integers in C++ are modelled as elements of the ring of integers modulo 2n for some number n specific to that unsigned integer type.
When you convert a signed integer to an unsigned integer you get the value in the ring of integers modulo 2n for the constant n for that unsigned type. For -1, this is 2n-1.
When you decrement 0 as an unsigned integer type, you get 2n-1.
These two values are the same.
See [basic.fundamental] 3.9.1/4 from the C++ standard:
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.
(Quote taken from N3690, a recent draft standard, but the truth it represents isn't going to change any time soon; the paragraph number might.)
Finding quotes on how conversion from a signed integer works would involve more standard chasing; but it ends up being what you want.
Yes, this behavior is guaranteed.
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.
Specifically considering the built-in pre-decrement and post-decrement operators:
[T]he expression
--xis exactly equivalent tox -= 1. ...
[T]he expressionx--modifies the value of its operand as if by evaluatingx -= 1
So the decrement operator does perform an arithmetic operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With