Order of evaluation between logical and assignment operators

139 views Asked by At

I know that the order of evaluation and precedence of operators in C are independent. But I get confused when there are multiple operators that mandates the order of evaluation.

For example:

a = b && c || d;

is parsed as:

a = ((b && c) || d);

How does the compiler evaluate this?

Does it evaluate (b && c), (if necessary) evaluate d, then evaluate the assignment operator which goes right to left?

Or does it evaluate the assignment operator first, then the && operator and then (if necessary) evaluate d?

2

There are 2 answers

4
Toby Speight On

In most cases in C, order of evaluation is unspecified.

In this case, we have logical operators, and they do have sequence points: b is fully evaluated before the start of evaluating c, for instance.

The assignment operator does not have a sequence point, so a may be computed before or after the value being assigned to it.

That's why it's unsafe to modify a variable that's used on both sides of such an operator (e.g. *++i = *i is undefined).

0
tstanisl On

From 6.5.16p3

An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue. The type of an assignment expression is the type the left operand would have after lvalue conversion. The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.

So the C standard does not specify the order in which a and ((b && c) || d) are evaluated. Moreover, if the result depends on evaluation order then the behavior is undefined.

All one can say is that:

  • b is evaluated before c or c is never evaluated if b evaluates to zero.
  • b && c is evaluated before d or d is not evaluated if (b && c) return non-zero value.
  • an object designated by l-value expression a is assigned after both ((b && c) || d) and a are evaluated.