Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > tricky assignment statemenent

Reply
Thread Tools

tricky assignment statemenent

 
 
ccwork
Guest
Posts: n/a
 
      01-17-2005
>There are two assignments here. In one assignment, p is modified. The
>prior value of p is arguably used to determine the new value stored

into
>p, as you explained, but it is _also_ read to determine at which

memory
>location the second assignment will happen, so it is not _only_ read

to
>determine the value stored, therefore undefined behavior.


There is something wrong. The first assignment is "p->next = q" and
"p" is _not_ modified. After this assignment value of "p" is _not_
changed; only "p->next" is changed. The second assignemnt is "p =
p->next =q" and "p" is going to hold the result of "p->next = q",
which is "q".

Consider "b = b * 10". According to your logic it will be undefined
since b is read to determine new value but also read to determine
memory for second assignment.
 
Reply With Quote
 
 
 
 
Chris Torek
Guest
Posts: n/a
 
      01-17-2005
[given "p = p->next = q" for suitable pointers p and q]

Someone -- name filed off but not by me and the person to whom I am
replying used the badly broken Google news posting interface -- wrote:

>>There are two assignments here. In one assignment, p is modified. The
>>prior value of p is arguably used to determine the new value stored

>into p, as you explained, but it is _also_ read to determine at which
>>memory location the second assignment will happen, so it is not
>>_only_ read to >determine the value stored, therefore undefined behavior.


In article <(E-Mail Removed) >
ccwork <(E-Mail Removed)> wrote:
>There is something wrong. The first assignment is "p->next = q" and
>"p" is _not_ modified.


This is correct, except that the word "first" is not appropriate --
there is no ordering implied yet.

>After this assignment value of "p" is _not_ changed; only "p->next"
>is changed. The second assignemnt is "p = p->next =q " and "p" is
>going to hold the result of "p->next = q", which is "q".


Yes. The problem comes about because (or "if", depending on how
you read the precise text of the C89 and C99 standards) the words
"before" and "after" are not applicable. There are those who
claim that a C compiler can treat:

a = b = c;

as if it read:

temp = c;
a = temp;
b = temp;

i.e., assign to the leftmost object, then assign to the middle
object.

Suppose this happens with "p = p->next = q". Then we get:

temp = q;
p = temp;
p->next = temp;

which does something quite different from:

temp = q;
p->next = temp;
p = temp;

If you believe that the C standard allows this runtime order of
operations, then the assignment "p = p->next = q" is undefined
and sometimes does the wrong thing. If you believe that the C
standard does not allow this runtime order of operations, then
the assignment is well-defined and always does the right thing.

While it would be very nice to say "clearly the folks who wrote
the standard *meant* to say it is well-defined", we do not get to
do that. We have to read what it actually says. Only the Anointed
Few who have authority to respond to Defect Reports can say
"this is what it means".

Since it is not clear, your best bet is to avoid the construct --
if you write:

p->next = q;
p = q; /* or p = p->next; */

your code will absolute, positively work every time. This is
probably worth the extreme exhaustion typing that extra line of
code may cause your fingers.

>Consider "b = b * 10". According to your logic it will be undefined
>since b is read to determine new value but also read to determine
>memory for second assignment.


This assignment is not very analagous; a better comparison might
be something like:

b = (b = b * 10) + 4;

except this is considerably worse than "p = p->next = q" (the case
with "b" here is clearly undefined, while the case with p is not
clear at all).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
 
 
 
Christian Bau
Guest
Posts: n/a
 
      01-17-2005
In article <(E-Mail Removed) >,
http://www.velocityreviews.com/forums/(E-Mail Removed) (ccwork) wrote:

> >There are two assignments here. In one assignment, p is modified. The
> >prior value of p is arguably used to determine the new value stored

> into
> >p, as you explained, but it is _also_ read to determine at which

> memory
> >location the second assignment will happen, so it is not _only_ read

> to
> >determine the value stored, therefore undefined behavior.

>
> There is something wrong. The first assignment is "p->next = q" and
> "p" is _not_ modified. After this assignment value of "p" is _not_
> changed; only "p->next" is changed. The second assignemnt is "p =
> p->next =q" and "p" is going to hold the result of "p->next = q",
> which is "q".
>
> Consider "b = b * 10". According to your logic it will be undefined
> since b is read to determine new value but also read to determine
> memory for second assignment.


Where is the "second assignment" ?
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      02-03-2005
On Mon, 17 Jan 2005 05:16:19 +0000, Chris Torek wrote:

....

>>After this assignment value of "p" is _not_ changed; only "p->next"
>>is changed. The second assignemnt is "p = p->next =q " and "p" is
>>going to hold the result of "p->next = q", which is "q".

>
> Yes. The problem comes about because (or "if", depending on how
> you read the precise text of the C89 and C99 standards) the words
> "before" and "after" are not applicable. There are those who
> claim that a C compiler can treat:
>
> a = b = c;
>
> as if it read:
>
> temp = c;
> a = temp;
> b = temp;
>
> i.e., assign to the leftmost object, then assign to the middle
> object.


I was just looking back at this, and IMHO it isn't quite as simple as that.
I would represent it as the following with & indicating "lvalue of" and *
"object designated by"

temp1 = c; /* Evaluation of operand c */
tempb = &b; /* Evaluation of operand b */
tempa = &a; /* Evaluation of operand a */
temp2 = temp1; /* Result of b = c */
*tempa = temp2; /* Execution of assignment to a */
*tempb = temp1; /* Execution of assignment to b */

I have no problem with *tempa = temp2 preceding *tempb = temp1. What I
don't accept is that *tempa = temp2 can precede tempb = &b, because
temp2 = temp1 cannot. Essentially you cannot execute an operator in the
abstract machine before you have evaluated its operands.

Lawrence
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Assignment operator self-assignment check Chris C++ 34 09-26-2006 04:26 AM
Augument assignment versus regular assignment nagy Python 36 07-20-2006 07:24 PM
a tricky if else(maybe not tricky but impossible) nirkheys@gmail.com C Programming 9 04-25-2006 06:13 PM
tricky assignment statemenent Ike Naar C Programming 22 01-15-2005 11:19 AM
tricky assignment statemenent ccwork C Programming 6 01-12-2005 03:59 AM



Advertisments