Order of evaluation

P

publictom

Is the following statement true?

"It is required that the operands to an operator be fully evaluated
before the operator itself is evaluated."

The only way I can think of that it would be practically possible to
violate this would be for subexpression like a += b to return its value
(a + b) for use in the parent expression, but leave it until some time
later before it assigned that value to a. Is this allowed?

If this statement above is true, then the following is defined:

int a = /*something*/, b = /*something else*/;
a ^= b ^= a ^= b;

A couple of people at this page:
http://c2.com/cgi/wiki?ThreeStarProgrammer, have said that the above
expression is undefined because it modifies 'a' twice without an
intervening sequence point. If operands have to be fully evaluated
before the operator can be evaluated, this is not undefined though,
because it is equivalent to (a ^= (b ^= (a ^= b))), in which each
operator with side-effects depends on the result of the next. Is it
undefined or not?

ps. Clearly the order of evaluation of the subexpressions in (a ^= b)
^= (a ^= b) is undefined - I'm certainly not disagreeing with that.

pps. If a and b were of a user-defined type, the ^= operator would be a
function call, and the parameters to a function call have to be
evaluated before the call, so in this case it would be defined.
 
V

Victor Bazarov

Is the following statement true?

"It is required that the operands to an operator be fully evaluated
before the operator itself is evaluated."
Yes.

The only way I can think of that it would be practically possible to
violate this would be for subexpression like a += b to return its value
(a + b) for use in the parent expression, but leave it until some time
later before it assigned that value to a. Is this allowed?

Yes, and it sometimes causes trouble if 'a' is changed twice before the
next sequence point.
If this statement above is true, then the following is defined:

int a = /*something*/, b = /*something else*/;
a ^= b ^= a ^= b;

Nope. This expression changes the value of 'a' and 'b' twice between the
sequence points.
A couple of people at this page:
http://c2.com/cgi/wiki?ThreeStarProgrammer, have said that the above
expression is undefined because it modifies 'a' twice without an
intervening sequence point. If operands have to be fully evaluated
before the operator can be evaluated, this is not undefined though,
because it is equivalent to (a ^= (b ^= (a ^= b))), in which each
operator with side-effects depends on the result of the next. Is it
undefined or not?

It is undefined. Evaluation of operands (obtaining the values) and side
effects taking place are two different things.
ps. Clearly the order of evaluation of the subexpressions in (a ^= b)
^= (a ^= b) is undefined - I'm certainly not disagreeing with that.

pps. If a and b were of a user-defined type, the ^= operator would be a
function call, and the parameters to a function call have to be
evaluated before the call, so in this case it would be defined.

Yes.

V
 
P

publictom

... Evaluation of operands (obtaining the values) and side
effects taking place are two different things.

It all comes clear to me now. Thanks very much for your help.
 
P

publictom

Just to make sure I've got this straight:
int a = 1, b = 2, c = 3;
(a = b) = c;
This is undefined too, isn't it? 'a' could end up containing either 2
or 3 as there are no sequence points between the two assignments.

Thanks,
Tom
 
V

Victor Bazarov

Just to make sure I've got this straight:
int a = 1, b = 2, c = 3;
(a = b) = c;
This is undefined too, isn't it? 'a' could end up containing either 2
or 3 as there are no sequence points between the two assignments.

That is a good question. Let me start the explanation by saying that
you're *incorrect* using the word "either" here. _If_ the behaviour is
undefined, *anything* can happen.

Now, to the actual thing. I have read the Standard (again) and can only
say that it's ambiguous at best. The exact text is "The result of the
assignment operation is the value stored in the left operand after the
assignment has taken place; the result is an lvalue." How should we
understand this? Maybe my bad English plays tricks on me, but I read
that sentence as dual in meaning. OOH, it can mean, "The result of the
assignment operation is only known after assignment is complete (and the
value is stored)". OTOH, it can mean, "The result of the assignment
operation is _the same_ as what _will be stored_ when the sequence point
is reached". If it's the former, then both expressions (the one you asked
about before and the one you're asking about here) are well-defined, since
assignment always takes place before the lvalue is returned. If it is the
latter that is true, then both forms are undefined.

I believe the safer would be interpret it as the latter. I am now unsure,
though, which one is the correct interpretation.

V
 
P

publictom

That is confusing, indeed. It is good advice to assume it is unsafe and
just avoid such things. I'm getting the feeling I should get a copy of
the standard, as well.
Thanks again for your help. Your English doesn't seem bad at all.
Tom
 
J

Joe Gottman

Is the following statement true?

"It is required that the operands to an operator be fully evaluated
before the operator itself is evaluated."

It is true in all except two cases: a && b and a || b. In the first case,
if a evaluates to false then a &&b must be false whatever the value of b is.
Similarly, in the second case if a evaluates to true then a || b must be
true whatever b is. In both these cases, the operator immediately returns
the correct value after the first operand is evaluated, and the second one
isn't evaluated at all. This is called "short-circuit evaluation".

Joe Gottman
 

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

Forum statistics

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

Latest Threads

Top