I attempted to write a function that increments an unsigned integer and checks if the result overflowed, by comparing the old value of the integer with the value after incrementing:
unsigned detect_overflow(unsigned x) {
if (x > ++x) {
std::cerr << "Overflow occurred: " << x - 1 << " -> " << x << std::endl;
}
return x;
}
However, it doesn't work when the comparison in the if
is written this way. Calling the function with UINT_MAX
leads to undetected overflow.
But if the condition in the if
is changed to use post-increment instead:
unsigned detect_overflow(unsigned x) {
if (x++ > x) {
std::cerr << "Overflow occurred: " << x - 1 << " -> " << x << std::endl;
}
return x;
}
then overflow is detected correctly:
Overflow occurred: 4294967295 -> 0
The same is true for the equivalent version of said function for detecting underflow.
What gives? I understand the difference between the value returned by post and pre-increment operators, but clearly my assumptions about how these values may be used in expressions containing side-effects are incorrect. What is going on here?