[Nickle]Sequencing of expressions with side effects
Keith Packard
nickle@nickle.org
Tue, 23 Jul 2002 13:47:19 -0700
Around 12 o'clock on Jul 23, Bart Massey wrote:
> > a = (int b = 2) ** b;
>
> Huh? The example you give has nothing to do with the order
> of evaluation of assignment, as near as I can tell
I was attempting to demonstrate the issue with the exponentiation operator
which is also right associative. In this case, a strict left-to-right
rule ensures that when 'b' is lexically in scope, the initializer has been
run. If the RHS of the '**' operator is evaluated before the LHS, the
initializer for 'b' won't have been run.
> 1. The meaning of an expression should never be changed by
> explicitly putting in the parentheses implied by
> precedence and associativity.
That's true in either evaluation order.
> 2. Expression evaluation should honor explicit parentheses:
> parenthesized subexpressions should always be evaluated
> before their containing expressions.
But that doesn't constrain the evaluation of the LHS of a binary operator
wrt the RHS. In a strict left-to-right world, you just start evaluating
the expression elements from left to right, executing the operators when
the appropriate operands have been evaluated:
a = (int b = 2) ** b;
r1 = ref(a)
r2 = ref(b)
r3 = 2
*r2 = r3
r4 = b
r5 = r3 ** r4
*r1 = r5
Consider this in the form of a parse tree:
=
/ \
a **
/ \
= b
/ \
b 2
A left-bearing depth-first walk of the tree yields the correct order of
evaluation.
>> a += b -> (poly* ap = &a), (*ap = *ap + b)
>
> Since a is required to be an lvalue, I'm not seeing how this
> matters. Maybe when a is of pointer type?
*a++ += b -> (poly *ap = a++), (*ap = *ap + b)
The important part is to compute the reference value only once.
Keith Packard XFree86 Core Team HP Cambridge Research Lab