Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to put increment/decrement operators inside ternary/conditional operators?

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 ); 
like image 284
jozxyqk Avatar asked Sep 08 '14 13:09

jozxyqk


People also ask

Can we use increment operator in if condition?

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.

What will happen if you use increment and decrement operators on constant?

Increment operator increases the value of the variable by 1. Decrement operator decreases the value of the variable by 1.

Why are increment and decrement operators not allowed in Python?

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.


2 Answers

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.

like image 103
T.C. Avatar answered Sep 22 '22 16:09

T.C.


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.

like image 37
CashCow Avatar answered Sep 22 '22 16:09

CashCow