Velocity Reviews > tricky assignment statemenent

# tricky assignment statemenent

Christian Bau
Guest
Posts: n/a

 01-04-2005
In article <(E-Mail Removed)> ,
Lawrence Kirby <(E-Mail Removed)> wrote:

> On Fri, 31 Dec 2004 05:50:38 +0000, Joona I Palaste wrote:
>
> > Ike Naar <(E-Mail Removed)> scribbled the following:
> >> Consider the following code:

>
> ...
>
> >> void f(struct s * q)
> >> {
> >> struct s * p = malloc(sizeof *p);
> >> if (p != 0)
> >> {
> >> p = p->next = q; /* is this safe? */
> >> }
> >> }

> >
> >> In the context given above, is the statement "p = p->next = q;"
> >> safe and equivalent to "p->next = q; p = q;"
> >> or does it invoke undefined behaviour because p is modified and
> >> dereferenced at the same time?

> >
> > I would consider it undefined behaviour, as there is no sequence point
> > between the operations "p=p->next" and "p->next=q" in the code.

>
> However the standard says "Furthermore, the prior value shall be read only
> to determine the value to be stored." In p = p->next = q the value
> assigned to p is the result of the expression p->next = q. In the abstract
> machine this expression must be evaluated fully in order to generate the
> value to be assigned. The access to p in p->next is part of that
> evaluation so it is very much being read in order to determine the new
> value. Before you start formulting your objections to this consider
> carefully the statements in the standard (5.1.2.3):

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.

petermcmillan_uk@yahoo.com
Guest
Posts: n/a

 01-04-2005

Ike Naar wrote:
> Emmanuel Delahaye <(E-Mail Removed)> wrote:
> : Ike Naar wrote on 31/12/04 :
> :> struct s * p = malloc(sizeof *p);
> :> if (p != 0)
> : Style preference:
> : if (p != NULL)
>
> Not to mention "if (p)", "if( p!=0 )" or "if (NULL != p)" .
> The discussion was not about style, though.
>
> :> p = p->next = q; /* safe or UB ? */
> : Huh! Gurus know that.
>
> That's why I turned to this very group. To ask the gurus.
>
> : Simple programmers write simple things that show
> : clearly the intention:
> : p->next = q;
> : p = p->next;
>
> And right they are. Do they also eat quiche ?
>
> Kind regards,
> Ike

I'm very interested in style, and personally I quite like :

if( p )

When p is a pointer I think it's clear what this means. What does
everybody else think about this?

Old Wolf
Guest
Posts: n/a

 01-04-2005
Ike Naar wrote:
> Consider the following code:
>
> #include <stdlib.h>
>
> struct s
> {
> /* ... */
> struct s * next;
> };
>
> void f(struct s * q)
> {
> struct s * p = malloc(sizeof *p);
> if (p != 0)
> {
> p = p->next = q; /* is this safe? */
> }
> }
>
> In the context given above, is the statement "p = p->next = q;"
> safe and equivalent to "p->next = q; p = q;"
> or does it invoke undefined behaviour because p is modified and
> dereferenced at the same time?

There's no sequence point; so it could be done in the order:
p = q;
p->next = q;
which doesn't give the result you intended. So the only
question is whether the behaviour is undefined, or
unspecified.
IMHO it's undefined: 'p->next = q' involves a read of p
which is NOT for the purpose of determining the value
to be written in 'p = q'.

pete
Guest
Posts: n/a

 01-06-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> if( p )
>
> When p is a pointer I think it's clear what this means. What does
> everybody else think about this?

I know that p is a pointer,
only because you told me so in text.

if (k != NULL)

gives you a good clue that k is a pointer

--
pete

Tim Rentsch
Guest
Posts: n/a

 01-06-2005
Christian Bau <(E-Mail Removed)> writes:

> In article <(E-Mail Removed)> ,
> Lawrence Kirby <(E-Mail Removed)> wrote:
>
> > On Fri, 31 Dec 2004 05:50:38 +0000, Joona I Palaste wrote:
> >
> > > Ike Naar <(E-Mail Removed)> scribbled the following:
> > >> Consider the following code:

> >
> > ...
> >
> > >> void f(struct s * q)
> > >> {
> > >> struct s * p = malloc(sizeof *p);
> > >> if (p != 0)
> > >> {
> > >> p = p->next = q; /* is this safe? */
> > >> }
> > >> }
> > >
> > >> In the context given above, is the statement "p = p->next = q;"
> > >> safe and equivalent to "p->next = q; p = q;"
> > >> or does it invoke undefined behaviour because p is modified and
> > >> dereferenced at the same time?
> > >
> > > I would consider it undefined behaviour, as there is no sequence point
> > > between the operations "p=p->next" and "p->next=q" in the code.

> >
> > However the standard says "Furthermore, the prior value shall be read only
> > to determine the value to be stored." In p = p->next = q the value
> > assigned to p is the result of the expression p->next = q. In the abstract
> > machine this expression must be evaluated fully in order to generate the
> > value to be assigned. The access to p in p->next is part of that
> > evaluation so it is very much being read in order to determine the new
> > value. Before you start formulting your objections to this consider
> > carefully the statements in the standard (5.1.2.3):

>
> 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.

Please consult Annex D. The formal model makes it clear (even if not
immediately obvious) that the semantics here are well defined.

Granted, Annex D is informative rather than normative. But the
question of whether "the prior value is read only to determine the
value to be stored" is at best open to debate. Even though the formal
model is informative and the statement about prior value is normative,
a clear statement from the formal model is a better indicator (at
least, IMO) than an unclear statement in informal prose.

lawrence.jones@ugs.com
Guest
Posts: n/a

 01-07-2005
Tim Rentsch <(E-Mail Removed)> wrote:
>
> Please consult Annex D. The formal model makes it clear (even if not
> immediately obvious) that the semantics here are well defined.

There is no formal model in the published standard -- it was a work in
progress that was considered too preliminary to publish, even
informatively. It does provide some guidance as to how some fraction of
the committee (which may be as small as the author and is certainly
smaller than the entire committee since there were people who objected
to it) thinks sequence points should work (if you can understand it at
all, which is not trivial), but it should not be considered in any way
definitive.

-Larry Jones

At times like these, all Mom can think of is how long she was in
labor with me. -- Calvin

Tim Rentsch
Guest
Posts: n/a

 01-07-2005
(E-Mail Removed) writes:

> Tim Rentsch <(E-Mail Removed)> wrote:
> >
> > Please consult Annex D. The formal model makes it clear (even if not
> > immediately obvious) that the semantics here are well defined.

>
> There is no formal model in the published standard -- it was a work in
> progress that was considered too preliminary to publish, even
> informatively. It does provide some guidance as to how some fraction of
> the committee (which may be as small as the author and is certainly
> smaller than the entire committee since there were people who objected
> to it) thinks sequence points should work (if you can understand it at
> all, which is not trivial), but it should not be considered in any way
> definitive.

A nice response posting. Informative; thoughtfully worded.

However, I don't think the comments above take away from the basic
conclusion. Even though the formal model was preliminary and is not
definitive, in the absence of any specific evidence to the contrary
it's more likely to provide an accurate interpretation for what the
standard intends than guessing what was intended based on one or two
sentences of informal prose.

One point seems fairly widely held: the language in the standard that
addresses this question is not as clear or as unambiguous as it should
be. So if I understand the differences between the two newsgroups,
it's appropriate at this point to bring up that topic in comp.std.c.

S.Tobias
Guest
Posts: n/a

 01-07-2005
Tim Rentsch <(E-Mail Removed)> wrote:

> Please consult Annex D.

May I ask which "Annex D" you're talkig about?
In C99 Annex D is "Universal character names for identifiers" and
in C89 - "Library summary".

--
Stan Tobias
mailx `echo (E-Mail Removed)LID | sed s/[[:upper:]]//g`

lawrence.jones@ugs.com
Guest
Posts: n/a

 01-08-2005
Tim Rentsch <(E-Mail Removed)> wrote:
>
> A nice response posting. Informative; thoughtfully worded.

Sorry, I'll try not to let it happen again.

> However, I don't think the comments above take away from the basic
> conclusion. Even though the formal model was preliminary and is not
> definitive, in the absence of any specific evidence to the contrary
> it's more likely to provide an accurate interpretation for what the
> standard intends than guessing what was intended based on one or two
> sentences of informal prose.

I don't think that's a valid conclusion. As I said (but perhaps not
explicitly enough), some members of the committee vehemently disagreed
with some parts of the proposed model, so I don't think it is any more
accurate than guessing based on the prose.

-Larry Jones

It's not denial. I'm just very selective about the reality I accept.
-- Calvin

Lawrence Kirby
Guest
Posts: n/a

 01-11-2005
On Tue, 04 Jan 2005 18:07:59 +0000, Christian Bau wrote:

> In article <(E-Mail Removed)> ,
> Lawrence Kirby <(E-Mail Removed)> wrote:
>
>> On Fri, 31 Dec 2004 05:50:38 +0000, Joona I Palaste wrote:
>>

....

>> > I would consider it undefined behaviour, as there is no sequence point
>> > between the operations "p=p->next" and "p->next=q" in the code.

>>
>> However the standard says "Furthermore, the prior value shall be read only
>> to determine the value to be stored." In p = p->next = q the value
>> assigned to p is the result of the expression p->next = q. In the abstract
>> machine this expression must be evaluated fully in order to generate the
>> value to be assigned. The access to p in p->next is part of that
>> evaluation so it is very much being read in order to determine the new
>> value. Before you start formulting your objections to this consider
>> carefully the statements in the standard (5.1.2.3):

>
> 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.

OK, the issue here is the meaning of "only". It is in there to (un)cover
cases like this:

j = (i = 2*i) + i;

Here i is accessed in the expression in a way that is used to
determine the value to be stored by the assignment to i, it is also
accessed in a way that is not. As such it violates the "only" requirement.

In p=p->next=q it is *only* accessed in the expression that calculates the
new value to be assigned. The inner assignment is part of that evaluation,
the fact that it has another side-effect on a distinct object is neither
here nor there, why should it be relevant?

Lawrence

 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 OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Chris C++ 34 09-26-2006 04:26 AM nagy Python 36 07-20-2006 07:24 PM nirkheys@gmail.com C Programming 9 04-25-2006 06:13 PM ccwork C Programming 3 02-03-2005 06:26 PM ccwork C Programming 6 01-12-2005 03:59 AM

Advertisments