473,883 Members | 1,521 Online

# x=(x=5,11)

Is this defined or not? Some people in ##c are saying that it has to
result in x being set to 11, i'm saying it's undefined. Who's right?
May 27 '06
111 4931

Gordon Burditt wrote:

Do you think this expression causes undefined behavior:

x = x = 11;
?

In this situation, I think it can, since there is no sequence point
and the two side effects on the same variable can occur SIMULTANEOUSLY.
That the two side effects are storing the same value is not relevant.

Yes, I do think it has undefined behaviour.

And rather than
x=(x=5,11);

Consider x=11; x^=(x=5,11);
Obviously this has undefined behaviour.

While it seems a bit bizarre, I know of nothing in the standard that
would prohibit a hardware implementation that needs to read a value
before storing a new value (an example might be hardware that can only
flip bits, not set/reset them) and so I expect this undefined behaviour
to extend to things like x=x=11; and x=(x=5,11);

And on this hardware, x=(x=5,11) wouldn't leave x=5 or x=11, it would
leave x with some undefined value.

This would also mean things like g=f(); where g is global and f()
modifies g would also have undefined behaviour.

Tim.

May 29 '06 #61
ri*****@cogsci. ed.ac.uk (Richard Tobin) wrote:
In article <11************ **********@j33g 2000cwa.googleg roups.com>,
Robert Gamble <rg*******@gmai l.com> wrote:
>> > x=(x=5,11);

"In simple assignment (=), the value of the right operand is
converted to the type of the assignment expression and replaces the
value stored in the object designated by the left operand."

Now how is it possible to obtain the value of the right operand and
convert it to the type of the assignment expression without evaluting
it before you store the result in x?

Clearly it's not possible to store the result before evaluating it,
but it's possible (indeed, easy!) to determine the value of (x=5,11)
before performing the assignment of 5 to x.

Possible, but not allowed. The assignment x=5 _must_ take place (in the
abstract machine) before the sequence point; the evaluation of 11, and
therefore also the final assignment of 11 to x, must take place after
the sequence point.

Richard
May 29 '06 #62
Old Wolf said:
Peter "Shaggy" Haywood wrote:
Old Wolf wrote:
I disagree. If the expression is 5 + 6 - 3, then the machine must
compute 5 + 6 before it subtracts 3 (notwithstandin g the as-if rule).

I'm not sure what other possibility you are trying to allow for here?
You're confusing order of evaluation with the parsing rules that
determine the grouping of sub-expressions. The expression 5 + 6 - 3
must be parsed as (5 + 6) - 3, but that doesn't mean the 5 + 6
sub-expression must be evaluated first.

Well, what are you going to subtract 3 from if you have
not yet computed (5 + 6) ?

You could subtract it from 0 and hold it as a temporary value:

tmp = 0 - 3
x = 0 + 5
y = 0 + 6
r = 0
r += x
r += y
r += tmp
Richard Heathfield quoted:
the order of evaluation of subexpressions and the
order in which side effects take place are both unspecified.

Nevertheless, I think there are other constraints, although I
cannot find supporting text in the standard (I posted to
comp.std.c asking). Specifically, that you cannot evaluate
(ie. obtain the value of) an expression containing an operator,
until you have evaluated any applicable operands of that operator.
Oh, but you can - see above, where tmp represents a complete evaluation of
the subtrahend and the subtraction. No further explicit subtraction
operations are carried out, although there is of course an implicit
subtraction involved in adding -3 to r.
Another example:

x = getchar();

Does the user have to press a key before a value can be
stored in 'x'?

No. I'll let you think about that one. :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 29 '06 #63
In article <44************ ****@news.xs4al l.nl>,
Richard Bos <rl*@hoekstra-uitgeverij.nl> wrote:
Clearly it's not possible to store the result before evaluating it,
but it's possible (indeed, easy!) to determine the value of (x=5,11)
before performing the assignment of 5 to x.
Possible, but not allowed. The assignment x=5 _must_ take place (in the
abstract machine) before the sequence point; the evaluation of 11, and
therefore also the final assignment of 11 to x, must take place after
the sequence point.

After checking the standard, I think you're right. The result must
be as if the x=5 assignment was performed before the evaluation of 11
and therefore before the other assignment.

-- Richard
May 29 '06 #64
Gordon Burditt wrote:

Old Wolf's lemma does NOT rule out the possibility that evaluating
x (the first one in x=(x=5,11) ) occurs before, not after, the
sequence point forced by the comma operator.
Correct. But the evaluation of the left-hand operand of the
assignment operator does not cause the value of x to be
read or written, so it does not fall foul of the rule about UB
due to multiple reads/writes between sequence points.

I didn't mention this as it is a red herring compared to
the main issue.

However, this code would certainly be undefined, for the reason
you mention:

*p = (p = q, 11);

where p and q are valid pointers to int.
I'd prefer to see a statement proved that at the comma
operator sequence point, x=5's side effect must be complete
and x=11's side effect MUST NOT HAVE STARTED. But the
evaluation of x may have started before the sequence point.
The evaluation of an operator's operands, does not mean that
the evaluation of the operator has started. In fact, my lemma
is that the assignment operator cannot be evaluated until
its right-hand operand has been evaluated (although the left
hand one may be evaluated at any time).

Note that 'evaluating' the left hand operand of the assignment
operator means determining the adddress at which the value
will be stored (it doesn't mean reading or writing that value).
Do you think this expression causes undefined behavior:

x = x = 11;

Yes, x is modified twice between sequence points.

May 29 '06 #65

Old Wolf wrote:
Gordon Burditt wrote:

Old Wolf's lemma does NOT rule out the possibility that evaluating
x (the first one in x=(x=5,11) ) occurs before, not after, the
sequence point forced by the comma operator.

Correct. But the evaluation of the left-hand operand of the
assignment operator does not cause the value of x to be
read or written, so it does not fall foul of the rule about UB
due to multiple reads/writes between sequence points.

What about writing to memory that requires erasing before the write can
take place?

Tim.

May 29 '06 #66
On 2006-05-29 06:46, Jordan Abel wrote:
2006-05-29 <ia************ *************** *****@4ax.com>, Jack Klein wrote:
On 27 May 2006 21:45:55 GMT, Jordan Abel <ra*******@gmai l.com> wrote
in comp.lang.c:
On 2006-05-27, en******@yahoo. com <en******@yahoo .com> wrote:
>
> Richard Tobin wrote:
>> In article <11************ **********@j33g 2000cwa.googleg roups.com>,
>> Robert Gamble <rg*******@gmai l.com> wrote:
>>
>> >> >> > x=(x=5,11);
>>
>> >"In simple assignment (=), the value of the right operand is
>> >converted to the type of the assignment expression and replaces the
>> >value stored in the object designated by the left operand."
>>
>> >Now how is it possible to obtain the value of the right operand and
>> >convert it to the type of the assignment expression without evaluting
>> >it before you store the result in x?
>>
>> Clearly it's not possible to store the result before evaluating it,
>> but it's possible (indeed, easy!) to determine the value of (x=5,11)
>> before performing the assignment of 5 to x.
>
> No, it isn't, because of the sequence point rule for the comma
> operator.

Repeat after me:

Sequence points define a partial ordering.

Wrong, a sequence point defines a total ordering as defined by the
standard.

The ordering provided by sequence points is manifestly partial.

f((a,b),(c,d));

Assuming a, b, c, d are all expressions with side-effects:

which is evaluated before the other, a or d?

Not claiming to be an expert but 6.5.2.2#10

"The order of evaluation of the function designator, the actual
arguments, and subexpressions within the actual arguments is
unspecified, but there is a sequence point before the actual call."

would suggest that the order of evaluation of the arguments is
undefined. Regarding the order of evaluation of a and b, the only thing
I can find that seems to apply would be 6.5.16#2

"The left operand of a comma operator is evaluated as a void expression;
there is a sequence point after its evaluation. *Then* the right operand
is evaluated; the result has its type and value.94) If an attempt is
made to modify the result of a comma operator or to access it after the
next sequence point, the behavior is undefined." (emphasis mine)

While it's not very clear I would suggest that the use of "Then" would
imply that the right operand is evaluated after the left.

Erik Wikström
--
"I have always wished for my computer to be as easy to use as my
telephone; my wish has come true because I can no longer figure
out how to use my telephone" -- Bjarne Stroustrup
May 29 '06 #67
go****@woodall. me.uk wrote:
Old Wolf wrote:
Gordon Burditt wrote:

Old Wolf's lemma does NOT rule out the possibility that evaluating
x (the first one in x=(x=5,11) ) occurs before, not after, the
sequence point forced by the comma operator.

Correct. But the evaluation of the left-hand operand of the
assignment operator does not cause the value of x to be
read or written, so it does not fall foul of the rule about UB
due to multiple reads/writes between sequence points.

What about writing to memory that requires erasing before the write can
take place?

Then this erasing is part of the write, and there may not be a sequence
point during a write (or during any "side effect", even).

May 29 '06 #68

Jordan Abel wrote:
2006-05-28 <<11*********** ***********@j55 g2000cwa.google groups.com>>, en******@yahoo. com wrote:

Jordan Abel wrote:
On 2006-05-27, en******@yahoo. com <en******@yahoo .com> wrote:
>
> Jordan Abel wrote:
>> On 2006-05-27, pemo <us***********@ gmail.com> wrote:
>> > Jordan Abel wrote:
>> >> Is this defined or not? Some people in ##c are saying that it has to
>> >> result in x being set to 11, i'm saying it's undefined. Who's right?
>> >
>> > x=(X=5,11)
>> >
>> > My reading [but what do I know!]
>> >
>> > X=paraen'ed-expression
>> >
>> > So, paraen'ed-expression must be evaluated first
>>
>> Why? The compiler doesn't need to emit code to evaluate it to know the value.
>>
>> I think that the statement
>>
>> char foo[9];
>> x=(x=sprintf(fo o,"hello"),spri ntf(foo," world!\n"));
>>
>> could do things in this order:
>>
>> x=8
>> x=5
>> set foo to "hello"
>> set foo to "world!\n"
>
> You're falling into the trap of arguing what a compiler
> might do rather than what a compiler is obliged to do
> by the Standard.

The "as if" rule applies.

Yes, and the code you posted doesn't behave as if
it were executed by the abstract machine.

The behavior of the abstract machine is not defined by the standard in
this case.

I know that's your opinion. The problem is you haven't
supported your statements with reasoning or citations from
the standard. Until you do, I don't see any reason to give

May 29 '06 #69

Tim Woodall wrote:
On 28 May 2006 13:34:28 -0700,
en******@yahoo. com <en******@yahoo .com> wrote:

Jordan Abel wrote:
On 2006-05-27, en******@yahoo. com <en******@yahoo .com> wrote:
>
> Richard Tobin wrote:
>> In article <11************ **********@j33g 2000cwa.googleg roups.com>,
>> Robert Gamble <rg*******@gmai l.com> wrote:
>>
>> >> >> > x=(x=5,11);
>>
>> >"In simple assignment (=), the value of the right operand is
>> >converted to the type of the assignment expression and replaces the
>> >value stored in the object designated by the left operand."
>>
>> >Now how is it possible to obtain the value of the right operand and
>> >convert it to the type of the assignment expression without evaluting
>> >it before you store the result in x?
>>
>> Clearly it's not possible to store the result before evaluating it,
>> but it's possible (indeed, easy!) to determine the value of (x=5,11)
>> before performing the assignment of 5 to x.
>
> No, it isn't, because of the sequence point rule for the comma
> operator.

Repeat after me:

Sequence points define a partial ordering.

You seem to think that sequence points are the only thing
that affect the partial ordering of expression evaluation.
That's false. In the expression a + b - c, the evaluation
of + must precede the evaluation of - in the abstract
machine. And compiled code must behave as if
the abstract machine would behave.

So you think

x ^= y ^= x ^= y;

has defined behaviour? After all, just as +/- associates L to R, ^=
associates R to L.

Of course not. The order of evaluation of the operators
doesn't determine the order in which the side effects
take place. Evaluating an assignment operator causes
a store to take place, but the side effect of updating the
stored value may take place at any point before the
next sequence point (and after the assignment operator
has been evaluated).

May 29 '06 #70

This thread has been closed and replies have been disabled. Please start a new discussion.