Here's an example
#include <iostream> using namespace std; int main() { int x = 0; cout << (x == 0 ? x++ : x) << endl; //operator in branch cout << "x=" << x << endl; cout << (x == 1 || --x == 0 ? 1 : 2) << endl; //operator in condition cout << "x=" << x << endl; return 0; }
output:
0 x=1 1 x=1
I understand the output, but is this undefined behaviour or not? Is the order of evaluation guaranteed in either case?
Even if guaranteed, I'm quite aware using increment/decrement can quickly become an issue for readability. I only ask as I saw similar code and was immediately unsure, given there are lots of examples of ambiguous/undefined use of increment/decrement operators, such as...
C++ does not define the order in which function parameters are evaluated. ↪
int nValue = Add(x, ++x);
The C++ language says you cannot modify a variable more than once between sequence points. ↪
x = ++y + y++
Because increment and decrement operators have side effects, using expressions with increment or decrement operators in a preprocessor macro can have undesirable results. ↪
#define max(a,b) ((a)<(b))?(b):(a) k = max( ++i, j );
x++ is post increment; this means that the value of x is used then it is incremented. If it is so, then x=0 should be used and the answer should be true.
Increment operator increases the value of the variable by 1. Decrement operator decreases the value of the variable by 1.
Python does not allow using the “(++ and –)” operators. To increment or decrement a variable in python we can simply reassign it. So, the “++” and “–” symbols do not exist in Python.
For the conditional operator (§5.16 [expr.cond]/p1):
Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.
For the logical OR operator (§5.15 [expr.log.or]/p1-2):
the second operand is not evaluated if the first operand evaluates to
true
. [...] If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression.
The behavior of your code is well-defined.
There is a guaranteed order of execution in ternary operators and boolean &&
and ||
operations, so there is no conflict in evaluation sequence points.
One at a time
cout << (x == 0 ? x++ : x) << endl; //operator in branch
Will always output x
but will increment it only if it was 0.
cout << (x == 1 || --x == 0 ? 1 : 2) << endl; //operator in condition
This is well defined too, if x
was 1 it will not evaluate the RHS, if it wasn't it will decrement it but --x
will never be 0, so it will be true iff x==1, in which case x
will also now be 0.
In the latter case if x is INT_MIN
it is not well-defined behaviour to decrement it (and it would execute).
That can't happen in the first case where x won't be 0 if it is INT_MAX
so you are safe.
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