logoalt Hacker News

rramadasstoday at 4:58 AM0 repliesview on HN

> What's the reason that C didn't define the order of this?

The OP article provides experimental details but annoyingly does not give the big picture w.r.t. C language specifications (provided in the links though).

There are three concepts at interplay here which is at the root of the problem; 1) Expressions (evaluates to a single value) 2) Statements (tells computer to perform an action) and 3) Sequence Points (specific moment during execution when all previous side-effects are guaranteed to be complete).

It is the sequence points during the evaluation of expressions which is important to understand here. From https://en.wikipedia.org/wiki/Sequence_point;

In C and C++, a sequence point defines any point in a computer program’s execution at which it is guaranteed that all side effects of previous evaluations will have been performed, and no side effects from subsequent evaluations have yet been performed. They are a core concept for determining the validity of and, if valid, the possible results of expressions...

1) An expression's evaluation can be "sequenced before" the evaluation of another expression. (Equivalently, the other expression's evaluation can be "sequenced after" that of the first.)

2) The expression's evaluation is "indeterminately sequenced", meaning that one is "sequenced before" the other, but which is unspecified.

3) The expression's evaluation is "unsequenced", meaning the operations in each expression may be interleaved.

The "Order of Evaluation" states; (from https://en.cppreference.com/c/language/eval_order)

"Order of evaluation of the operands of any C operator, including the order of evaluation of function arguments in a function-call expression, and the order of evaluation of the subexpressions within any expression is unspecified (except where noted below)."

The "Single Update Rule" states; (from https://www.accellera.org/images/eda/sv-bc/0282.html)

Between consecutive "sequence points" an object's value can be modified only once by an expression. The C language defines the following sequence points:

       Left operand of the logical-AND operator (&&).
       Left operand of the logical-OR operator (||).
       Left operand of the comma operator.
       Function-call operator.
       First operand of the conditional operator.
       The end of a full initialization expression.
       The expression in an expression statement.
       The controlling expression in a selection (if or switch) statement.
       The controlling expression of a while or do statement.
       Each of the three expressions of a for statement.
       The expression in a return statement.
Putting all of the above together in OP's code snippet; The "single update rule" fails for the expression since the variable a is modified multiple times between two consecutive sequence points and hence the result is UB.

For more detailed explanations, see Angelika Langer's Sequence Points and Expression Evaluation in C++ - https://angelikalanger.com/Articles/VSJ/SequencePoints/Seque...