B
Ben Pfaff
Richard Heathfield said:(e-mail address removed) said:
That is always true.
The best that the rest of us can hope for is to answer a question
earlier than Chris, or to answer a question that he doesn't.
Richard Heathfield said:(e-mail address removed) said:
That is always true.
Even if that ridiculous claim were true,
it isn't responsive
to the OP's question. Does the intermediate assignment
influence what value is assigned to a? The answer to that
is YES.
pete said:The ridiculous claim is true.
The topic comes up on this newsgroup from time to time,
usually in the form of "p = p->next = q"
You can look it up next time you're online.
http://groups.google.com/group/comp.lang.c/search?group=comp.lang.c&q="p+=+p->next+=+q"
http://groups.google.com/group/comp.lang.c/msg/1c7e2102fd256d79
"The p = p->next = q problem is also a real problem that came from
a program I was writing when I posted a question about it here
years ago." -- Ben Pfaff
No.
The value of the intermediate assignment
influences what value is assigned to a,
but that value is known prior to the side effect
of the actual assignment taking place.
If you have
unsigned char uc;
unsigned int ui;
ui = uc = -1;
that can be translated as either
uc = UCHAR_MAX;
ui = UCHAR_MAX;
or
ui = UCHAR_MAX;
uc = UCHAR_MAX;
The order in which the side effects take place doesn't matter.
OP's question is entirely an issue of
side effects not being ordered between sequence points.
Any compiler that compiles p = p->next = q as storing into p
before fetching p->next is simply broken. Operands are
evaluated before the operator they're operands for, and
operators are evaluated before they produce a value--that's
just how C semantics work (in a C abstract machine of course).
Ben said:Do you have any citations to back up your assertions?
In the p = p->next = q thread discussion, a lot of people quoted:
N869
6.5 Expressions
[#2] Furthermore, the prior value
shall be accessed only to determine the value to be
stored.60)
60)This paragraph renders undefined statement expressions
such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a = i;
... but I don't think that's really what makes the case for
undefinedness,
because that would imply that there is something wrong with
p = p->next
and I don't think that there is anything wrong with
p = p->next
I think it's just simply that assignments aren't sequence points,
which is what the problem is with
p = p->next = q.
I'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
Richard said:I'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
but
p=(p->next=q);
is fine? I hope .
Richard said:I'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
but
p=(p->next=q);
is fine? I hope .
No. Whether you write
a = b = c;
or
a = (b = c);
does not change anything -- apart from clarifying your intent.
You still are modifying p twice between sequence points; parentheses
do not introduce new sequence points.
If you want to be on the safe side, you can only do
p->next = q, p = p->next;
which IMO does not give you any advantage over
p->next = q;
p = p->next;
Cheers
Michael
Richard G. Riley said:I'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
but
p=(p->next=q);
is fine? I hope .
Richard G. Riley said:a=b=c=1;
Whats the problem with the above?
pete said:Ben said:Do you have any citations to back up your assertions?
I think he's confused about sequence points.
Some of the standard's function operator descriptions
seem to order the sequence of events between sequence points,
without proper respect to the concept of sequence points.
Here, we see the standard claim that the postfix increment
takes place after the result is obtained:
N869
6.5.2.4 Postfix increment and decrement operators
[#2] The result of the postfix ++ operator is the value of
the operand. After the result is obtained, the value of the
operand is incremented.
But, if we look at
N869
5.1.2.3 Program execution
[#16] EXAMPLE 7
"sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));
but the actual increment of p can occur at any time between
the previous sequence point and the next sequence point "
... we see the standard deny any ordering of events
between sequence points.
Michael Mair said:Richard said:butI'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
p=(p->next=q);
is fine? I hope .
No. Whether you write
a = b = c;
or
a = (b = c);
does not change anything -- apart from clarifying your intent.
You still are modifying p twice between sequence points
Micah said:Richard said:I'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
but
p=(p->next=q);
is fine? I hope .
No. Whether you write
a = b = c;
or
a = (b = c);
does not change anything -- apart from clarifying your intent.
You still are modifying p twice between sequence points
Well, no he's not. But he's reading its prior value for purposes other
than to determine the value stored, so same deal.
Ben said:Do you have any citations to back up your assertions?
pete said:I think he's confused about sequence points.
Some of the standard's function operator descriptions
seem to order the sequence of events between sequence points,
without proper respect to the concept of sequence points.
Here, we see the standard claim that the postfix increment
takes place after the result is obtained:
N869
6.5.2.4 Postfix increment and decrement operators
[#2] The result of the postfix ++ operator is the value of
the operand. After the result is obtained, the value of the
operand is incremented.
But, if we look at
N869
5.1.2.3 Program execution
[#16] EXAMPLE 7
"sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));
but the actual increment of p can occur at any time between
the previous sequence point and the next sequence point "
... we see the standard deny any ordering of events
between sequence points.
Micah said:Michael Mair said:Richard said:I'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
but
p=(p->next=q);
is fine? I hope .
No. Whether you write
a = b = c;
or
a = (b = c);
does not change anything -- apart from clarifying your intent.
You still are modifying p twice between sequence points
Well, no he's not. But he's reading its prior value for purposes other
than to determine the value stored, so same deal.
The order in which
_side effects_ take place is unspecified, but _some_
evaluation must precede _any_ side effect, because it is
evaluations that produce side effects.
The "at any time"
in the comment above means relative to other side effects.
Micah said:Michael Mair said:Richard G. Riley schrieb:
I'm coming around to thinking that 6.5 [#2] is relevant, and that
p = p->next = q
is undefined, and not just unspecified.
but
p=(p->next=q);
is fine? I hope .
No. Whether you write
a = b = c;
or
a = (b = c);
does not change anything -- apart from clarifying your intent.
You still are modifying p twice between sequence points
Well, no he's not.
But he's reading its prior value for purposes other
than to determine the value stored, so same deal.
Look again. Reading p is necessary to evaluate p->q = next,
Ben said:Do you have any citations to back up your assertions?
"Evaluation of an expression may _produce_ side effects."
"[At sequence points,] all side effects of _previous_
evaluations shall be complete [...]."
"In the abstract machine, all expressions are evaluated
_as specified by the semantics_."
OK.
"[An operator] may specify an operation to be performed
(which _in turn_ may _yield a value_ [...], _produce_ a
side effect, or some combination thereof) [...]."
"The syntax specifies the precedence of operators _in the
evaluation of_ an expression [...]."
"[Except ...], _the order of evaluation of subexpressions_
and _the order in which side effects take place_ are both
unspecified." (Not "order of A and B" but "order of A" and
"order of B".)
Keeping these in mind, read through section 6.5, noting
which paragraphs are marked "Semantics". Expressions
are evaluated "as specified by the semantics".
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.