Operator evaluation order

B

boltar2003

Perhaps this is a stupid question, but can someone explain why the
operator evaluation order differs for assignment compared to mathematic
operators when there is only a single operator type in the expression?

Eg:

a1 = a2 = a3 = a4 will evaluate as a3=a4, a2=a3, a1=a2

but

a1 + a2 + a3 + a4 will evaluate as a1=a2, a1=a3, a1=a4

Why the difference?

B2003
 
B

boltar2003

On Thu, 12 May 2011 10:06:32 +0000 (UTC)
a1 + a2 + a3 + a4 will evaluate as a1=a2, a1=a3, a1=a4

Sorry , that should have read a1+a2, a1+a3, a1+a4

B2003
 
M

Michael Doubez

Perhaps this is a stupid question, but can someone explain why the
operator evaluation order differs for assignment compared to mathematic
operators when there is only a single operator type in the expression?

Eg:

a1 = a2 = a3 = a4 will evaluate as a3=a4, a2=a3, a1=a2

but

a1 + a2 + a3 + a4 will evaluate as a1+a2, a1+a3, a1+a4

Why the difference?

Because the standard says that = operator groups right-to-left
(§5.17/1) while + operator groups left-to-right (§5.7/1).
 
B

boltar2003

Because the standard says that =3D operator groups right-to-left
(=A75.17/1) while + operator groups left-to-right (=A75.7/1).

Fair enough. Do you know why assignment doesn't group left to right too?

B2003
 
B

boltar2003

Then you have to write "5 = n" to assign 5 to n.

No you wouldn't. You're confusing the grouping order with left hand side and
right hand side in the actual expression.

B2003
 
N

Nobody

Fair enough. Do you know why assignment doesn't group left to right too?

Because the LHS of an assignment must be an lvalue (roughly, something
which has associated storage: a variable, a structure field, the result of
dereferencing a pointer with * or [], etc).

If "=" was left-associative, the expression:

a1 = a2 = a3 = a4

would be equivalent to:

((a1 = a2) = a3) = a4

But "(a1 = a2) = a3" makes no more sense than "(1 + 2) = a3".

OTOH, the expression:

a1 = (a2 = (a3 = a4))

doesn't have this problem, as the LHS is always an lvalue.
 
V

Victor Bazarov

Fair enough. Do you know why assignment doesn't group left to right too?

<shrug> Seems rather logical to conclude that

a = b = c = 5;

actually means "all values become 5" instead of "'a' becomes the same as
'b', then the same as 'c', then 5", since the latter sequence (which is
what it would be if assignment grouped left to right) doesn't change the
values of 'b' and 'c' and changes 'a' thrice (which seems rather
unnecessary).

V
 
V

Victor Bazarov

Fair enough. Do you know why assignment doesn't group left to right too?

Because the LHS of an assignment must be an lvalue (roughly, something
which has associated storage: a variable, a structure field, the result of
dereferencing a pointer with * or [], etc).

If "=" was left-associative, the expression:

a1 = a2 = a3 = a4

would be equivalent to:

((a1 = a2) = a3) = a4

But "(a1 = a2) = a3" makes no more sense than "(1 + 2) = a3".

It makes *some* sense. You actually are allowed to write that (try it,
you might be surprised). Since assignment returns a reference, you can
keep assigning to it. The expression

(a1 = a2) = a3

is *logically* equivalent to (a1 = a2, a1 = a3), except for the sequence
point, which doesn't exist in the first expression, and thus gives the
first expression, while legitimate syntactically, undefined behavior
(unless I missed something).
OTOH, the expression:

a1 = (a2 = (a3 = a4))

doesn't have this problem, as the LHS is always an lvalue.

The result of an assignment is an lvalue with built-in types and with
the compiler-provided assignment operator for classes. That's why you
can do

SomeClass a, b, c;
(a = b) = c;

without a problem since the assignment for classes is a function call
and as such provides an extra sequence point (unlike with built-in
types), so no undefined behavior there.

V
 
M

Michael Doubez

Fair enough. Do you know why assignment doesn't group left to right too?

I don't understand the others' answer. I would simply say that the
semantic intended from base type is that all variable get the same
value. But you only now it from the right most value, thus it makes
sense to have right grouping:
a1 = ( a2 = ( a3 = a4 ) );

Concerning the arithmetic operators, I guess it is because of
asymmetric operators such as '-' which group left in math notation: 9
- 3 - 2 != 9 - ( 3 - 2 ). In order to be coherent with mathematical
notation, asymmetric arithmetic operators group left and the same
convention was kept for symmetric ones.
 
J

Johannes Schaub

Perhaps this is a stupid question, but can someone explain why the
operator evaluation order differs for assignment compared to mathematic
operators when there is only a single operator type in the expression?

Eg:

a1 = a2 = a3 = a4 will evaluate as a3=a4, a2=a3, a1=a2

This is not true with regard to evaluation order.

The compiler can evaluate "a1" before evaluating "a3". It is true merely
with regard to assignment. That is, it will assign to a1 the value of a2
that it has after assigning to a2 the value of a3 that it has after
assigning to a3 the value of a4.
 
J

Joshua Maurice

It makes *some* sense.  You actually are allowed to write that (try it,
you might be surprised).  Since assignment returns a reference, you can
keep assigning to it.  The expression

    (a1 = a2) = a3

is *logically* equivalent to (a1 = a2, a1 = a3), except for the sequence
point, which doesn't exist in the first expression, and thus gives the
first expression, while legitimate syntactically, undefined behavior
(unless I missed something).

If the operator= is a built-in operator on fundamental types, then
yes. If the operator= is an overloaded operator, then it's a function
call, which brings in sequence points, making it not UB (but still bad
code style).
 
M

Michael Doubez

This is not true with regard to evaluation order.

The compiler can evaluate "a1" before evaluating "a3".

What do you mean ? If a1 is a variable, there is nothing to evaluate.
It is true merely
with regard to assignment. That is, it will assign to a1 the value of a2
that it has after assigning to a2 the value of a3 that it has after
assigning to a3 the value of a4.

I think there are many factors concerning the evaluation of an
expression and we are all catching on something different.

Just to sum up things. When evaluating an expression, there are:
1 the precedence of operators: some operators are evaluated before
others; ex: * is evaluated before +
2 the grouping between operators of same precedence: some are
grouped from left to right other right to left
3 the evaluation of the parameters: for a given resolved expression
regarding precedence and grouping, parameters are evaluated in any
order (I left out shortcuts)
4 the sequence point: some operators define a sequence others don't
 
M

Michael Doubez

Perhaps you could state what in "the others' answer" is not clear to you.

That from a question regarding grouping, we end up with consideration
about sequence points and exotics use of operator=.

That doesn't concern your answer at 13h56 which my reader didn't show
until after I posted my message.
 
M

Michael Doubez

That from a question regarding grouping, we end up with consideration
about sequence points and exotics use of operator=.

That doesn't concern your answer at 13h56 which my reader didn't show
until after I posted my message.

I mean 13h48. Well, whatever.
 
N

Nobody

It makes *some* sense. You actually are allowed to write that (try it,
you might be surprised). Since assignment returns a reference, you can
keep assigning to it.

Oops. I thought that I was on c.l.c.

For C++, the answer (regarding associativity) is "because that's how C
behaves".
 
J

James Kanze

Fair enough. Do you know why assignment doesn't group left to right too?

Probably utility considerations. What use would multiple
assignments be if "a = b = c" meant "(a = b) = c"?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top