x=(x=5,11)

E

ena8t8si

Tim said:
The result of x=(x=5,11); is to set x to the value 11, with
no undefined behavior.

If x is volatile, there will be two stores to x, the first store
storing the value 5, the second store storing the value 11.
Well I disagree. The side effects of x=5 must be evaluated before the
side effects of 11, but nothing requires the side effects of the x=()
assignment to be evaluated after the side effects of the x=5
assignment.[/QUOTE]

You're welcome to your opinion, but don't expect to convince
anyone without backing it up with language from the Standard.

In fact, the Standard does require that an expression be evaluated
before its value is produced, as I have explained at length in a
previous thread.
 
T

Tim Woodall

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.

Tim.
 
R

Richard Heathfield

(e-mail address removed) said:
In the expression a + b - c, the evaluation of + must precede the
evaluation of - in the abstract machine.

C99, 6.5(3): Except as specified later (for the function-call (), &&, ||,
?:, and comma operators), the order of evaluation of subexpressions and the
order in which side effects take place are both unspecified.

In the expression a + b - c, the abstract machine is under no obligation to
evaluate + before - or vice versa. Indeed, even a, b, and c themselves
might be evaluated in any order.

To bring this back into the context of the thread topic, it is clear that
the onus is on the programmer to ensure that the result produced is the
result the programmer expected - and the way to do that is to write clear,
simple code that removes the possibility of undefined behaviour, without
being forced to rely on (e-mail address removed)'s assurance that this possibility
does not exist.

In this case, this translates to replacing:

x=(x=5,11);

with:

x = 11;
 
J

Jordan Abel

Jordan said:
Jordan Abel 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(foo,"hello"),sprintf(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.
 
J

Jordan Abel

Jordan Abel wrote:
[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?

To use another example:

#include <stdlib.h>
int main(void) {
int *p = 0;
exit(0), *p;
}

Is this a valid C program?

I believe there is no significant difference between this, and
x=(x=5,11). In both cases, the behaviour is defined if and only if the
right operand of the , operator is not ever evaluated before the left
operand is, in both cases there are no side effects in the evaluation
of the right operand, and in both cases and the question is whether the
as-if rule can introduce undefined behaviour when there would otherwise
not be any. Do you agree that this example has the same problem? And if
not, why not? (The reason I'm using this example is because disallowing
it is much more surprising to me than disallowing your original code.)

There is no part of the expression x=(x=5,11) that is not reached.

This does seem a lot like the p=p->next=q discussion, which i'd
forgotten until now, and which I don't think we ever came to a consensus
on.
 
O

Old Wolf

Richard said:
(e-mail address removed) said:


In the expression a + b - c, the abstract machine is under no obligation to
evaluate + before - or vice versa. Indeed, even a, b, and c themselves
might be evaluated in any order.

I disagree. If the expression is 5 + 6 - 3, then the machine must
compute 5 + 6 before it subtracts 3 (notwithstanding the as-if rule).

I'm not sure what other possibility you are trying to allow for here?
 
R

Richard Heathfield

Old Wolf said:
I disagree. If the expression is 5 + 6 - 3, then the machine must
compute 5 + 6 before it subtracts 3 (notwithstanding the as-if rule).

Please explain your reasoning in the light of 6.5(3), which I cited
upthread.
 
O

Old Wolf

Jordan said:
There is no part of the expression x=(x=5,11) that is not reached.

Jordan, in all your posts on this thread you seem to ignore
the fact that the comma operator introduces a sequence point.

The rules of C are that nothing after a sequence point can
be evaluated until all side-effects from expressions prior to
the sequence point have been evaluated.

It is not possible to evaluate "11" before the assignment of
5 to x has completed.

It is not possible to assign 11 to x, before 11 has been evaluated.

By the logic that you are using, there might as well be no
sequence points; for example you would have to say that:

x = 1;
x = 2;

causes undefined behaviour because before 1 is assigned
to x, the compiler can "see" that 2 is going to be assigned
to x.
 
J

Jordan Abel

Jordan, in all your posts on this thread you seem to ignore
the fact that the comma operator introduces a sequence point.

Sequence points are fine, as far as they go, but you're forgetting that
they define a partial ordering.
 
G

Guest

Richard said:
(e-mail address removed) said:


C99, 6.5(3): Except as specified later (for the function-call (), &&, ||,
?:, and comma operators), the order of evaluation of subexpressions and the
order in which side effects take place are both unspecified.

This doesn't address the issue.
In the expression a + b - c, the abstract machine is under no obligation to
evaluate + before - or vice versa. Indeed, even a, b, and c themselves
might be evaluated in any order.

a, b, and c may be evaluated in any order, but the code *must* behave
as if the addition is done before the subtraction. The subtraction may
be done before the addition if and only if in every case, the same
result is generated, because otherwise the as-if rule doesn't apply.
(See also 5.1.2.3#14.)
 
G

Guest

Jordan said:
Jordan said:
Jordan Abel 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(foo,"hello"),sprintf(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.

In the abstract machine, the behaviour is well-defined, since getting
the result of the , operator requires getting the result of the right
operand, and since the evaluation of the outer = operator cannot cross
a sequence point, it must happen in whole only after the sp introduced
by the , operator.
 
K

Kenneth Brody

Robert said:
Kenneth said:
Robert Gamble wrote: [...]
6.5.16.1p2:
"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?

Well, "the value of the right operand" can be determined without
necessarily introducing all of the side effects. Extending that
logic, the following should be "defined" as well:

x = (x++,11);

Right, and it is.

I keep forgetting that the comma operator is a sequence point, probably
because I would never write code such as the above. That, and it comes
up here with "f(x++,x++)" and people have to point out that the comma
here is not "the comma operator".

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
R

Richard Heathfield

Harald van D?k said:
a, b, and c may be evaluated in any order, but the code *must* behave
as if the addition is done before the subtraction. The subtraction may
be done before the addition if and only if in every case, the same
result is generated, because otherwise the as-if rule doesn't apply.

Personally, I don't think a conforming program can tell the difference.
(See also 5.1.2.3#14.)

Examples are not normative, but I do take your point.
 
P

Peter Shaggy Haywood

Groovy hepcat Old Wolf was jivin' on 28 May 2006 15:35:46 -0700 in
comp.lang.c.
Re: x=(x=5,11)'s a cool scene! Dig it!
I disagree. If the expression is 5 + 6 - 3, then the machine must
compute 5 + 6 before it subtracts 3 (notwithstanding 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.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
R

Robert Gamble

Peter said:
Groovy hepcat Old Wolf was jivin' on 28 May 2006 15:35:46 -0700 in
comp.lang.c.
Re: x=(x=5,11)'s a cool scene! Dig it!


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.

Regardless of which part of the expression is evaluated first, the
addition must occur before the subtraction, I think this is Old Wolf
was trying to convey.

Robert Gamble
 
O

Old Wolf

Jordan said:
Sequence points are fine, as far as they go, but you're forgetting that
they define a partial ordering.

The phrase "partial ordering" is not used by the Standard. Can you
explain what you mean, and provide supporting quotes?

The following quotes are relevant:

C99 6.5.16#3 (Assignment operator)
The side effect of updating the stored value of the left operand
shall occur between the previous and the next sequence point.

C99 6.5.17#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

C99 5.1.2.3#2
At certain specified points in the execution sequence called
sequence points, all side effects of previous evaluations shall
be complete and no side effects of subsequent evaluations
shall have taken place.

Old Wolf's lemma:
The right operand of the assignment operator must be evaluated
before the assignment operator's side-effect can take place.

We are evaluating the expression (x = 5, 11).
6.5.17#2 says that there is a sequence point after (x=5) is
evaluated and before "11" is evaluated.
5.1.2.3#2 and 6.5.16#3 both say that the side-effect of (x=5)
must be complete before this sequence point.
Old Wolf's lemma says that storing the result of (x=5, 11)
in x must occur after (x=5,11) is evaluated.

Therefore, according to 6.5.16#3 and 5.1.2.3#2, at the comma
operator sequence point, x=5's side effect must be complete
and x=11's side effect must not be complete.

The only way you can deny this argument is to deny my
lemma; so you are claiming that in the situation:

x = (expression)

the side-effect of updating x can occur before (expression) is
evaluated.

Agree?

This is absurd. For example:

x = 1;
x = (printf("x is %d\n", x), 11);

Do you still call this undefined and can it print 11?

How about
int f() { printf("x is %d\n", x); return 11; }
...
x = 1;
x = f();

How far can you draw your bow?
 
O

Old Wolf

Peter said:
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) ?

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.

(By 'any applicable' I exclude cases where there are operands
which are never evaluated, eg. with && or sizeof).

Richard, please answer the above question if you can.
Another example:

x = getchar();

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

I contend that the assignment operator cannot be evaluated
until getchar() has been evaluated (ie. called).
 
J

Jordan Abel

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?

There's a sequence point - there are even two of them [three if you know
where to look]. So clearly you should be able to know from that which of
the following orders abcd acbd acdb cdab cadb cabd is used.
 
G

Gordon Burditt

Sequence points are fine, as far as they go, but you're forgetting that
The phrase "partial ordering" is not used by the Standard. Can you
explain what you mean, and provide supporting quotes?

A partial ordering is an ordering inposed on a sequence of events
by constraints of the form (X occurs before Y), (or more explicitly,
X finishes occurring before Y starts) but which does not totally
determine the order of the events.

One of the more obvious things that I don't think the standard
states is that an operator cannot be evaluated until its operands
have been evaluated, unless it's one of the C operators that
conditionally may not evaluate one of its operands (and these impose
sequence points anyway).

You call a more specific version of this applied to an assignment
operator "Old Wolf's Lemma" below.

For example: a + b cannot be evaluated until after you evaluate
both a and b, but the relative ordering of the evaluation of a
and b is not specified.
The following quotes are relevant:

C99 6.5.16#3 (Assignment operator)
The side effect of updating the stored value of the left operand
shall occur between the previous and the next sequence point.

C99 6.5.17#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

C99 5.1.2.3#2
At certain specified points in the execution sequence called
sequence points, all side effects of previous evaluations shall
be complete and no side effects of subsequent evaluations
shall have taken place.

Old Wolf's lemma:
The right operand of the assignment operator must be evaluated
before the assignment operator's side-effect can take place.

Also, the LEFT operand of the assignment operator must be evaluated
before the assignment operator's side-effect can take place.
We are evaluating the expression (x = 5, 11).
6.5.17#2 says that there is a sequence point after (x=5) is
evaluated and before "11" is evaluated.
5.1.2.3#2 and 6.5.16#3 both say that the side-effect of (x=5)
must be complete before this sequence point.
Old Wolf's lemma says that storing the result of (x=5, 11)
in x must occur after (x=5,11) is evaluated.

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.
Therefore, according to 6.5.16#3 and 5.1.2.3#2, at the comma
operator sequence point, x=5's side effect must be complete
and x=11's side effect must not be complete.

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.
I am not sure whether this is permitted to cause nuclear
explosions when run on a DeathStation 9000.


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.

Gordon L. Burditt
 

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,787
Messages
2,569,627
Members
45,328
Latest member
66Teonna9

Latest Threads

Top