Re: What is a sequence point?

From: Tim Rentsch (txr_at_alumnus.caltech.edu)
Date: 02/16/05


Date: 16 Feb 2005 12:19:30 -0800

CBFalconer <cbfalconer@yahoo.com> writes:

> infobahn wrote:
> > Luke Wu wrote:
> >> infobahn wrote:
[redundant quoting snipped]
> >>
> >> (p = (p->next = q))
> >>
> >> Now, whether p->next or q evaluates first is unspecified. But it
> >> doesn't matter, p->next = q happens before p = p->next
> >
> > The evaluations of p, p->next, and q can happen in any order.
>
> However p->next is never evaluated, it is simply stored into.

It's true that a compiler need not emit any code specifically for the
expression 'p->next'. But in the abstract machine 'p->next' is
evaluated. Looking at the semantics of the '->' operator in section
6.5.2.3, p4:

    A postfix expression followed by the -> operator and an identifier
    designates a member of a structure or union object. The value is
    that of the named member of the object to which the first
    expression points, and is an lvalue.

In the abstract machine, it is evaluating the expression that yields
its value. Also, expressions that are lvalue's are evaluated:
section 6.3.2.1, p1, says

    An lvalue is an expression with an object type or an incomplete
    type other than void; if an lvalue does not designate an object
    when it is evaluated, the behavior is undefined.

Evaluating an lvalue does not mean getting the stored value; that
is discussed separately, in 6.3.2.1, p2:

    Except when it is the operand of the sizeof operator, the unary &
    operator, the ++ operator, the --operator, or the left operand of
    the . operator or an assignment operator, an lvalue that does not
    have array type is converted to the value stored in the designated
    object (and is no longer an lvalue).

> The
> thing that is evaluated is (p->next = q).

The expression '(p->next = q)' is also evaluated. That evaluation
both yields the value and produces the side effect. The side effect
might not complete until later, but it is produced by evaluating the
expression - section 5.1.3.2.

> I don't think this makes
> any difference to the argument, because there is no argument about
> what gets stored in p. The argument would be about where the
> storage into (p->next) goes, and that is what is undefined here.

Of the various people responding to the 'p = p->next = q;' question,
only Chris Torek was conscientious enough to note the discussions in
comp.std.c on this and related topics. Rather than get into those
arguments again here, anyone interested is invited to see the
discussions in comp.std.c, which are still going on.

Incidentally, even if one admits the possibility that the evaluation
of the containing expression 'p = p->next = q' might precede the
evaluation of the contained expression 'p->next = q' (which question
is still being debated), evaluation order is only "unspecified", not
"undefined".



Relevant Pages

  • Re: gcc: pointer to array
    ... > any use as an lvalue will result in undefined behaviour. ... Clearly an evaluation of an integer constant isn't supposed to ... cause undefined behavior. ... >> be) an expression with an object type or an incomplete type ...
    (comp.lang.c)
  • Re: C1X Draft
    ... pointer object whose current value is a null pointer, ... evaluated *as an lvalue*. ... but anything that triggers undefined behaviour during the evaluation ... It's an exception to the rule that the evaluation of an expression ...
    (comp.std.c)
  • Re: gcc: pointer to array
    ... > any use as an lvalue will result in undefined behaviour. ... with an object type), and that evaluating it does not invoke undefined ... > operator requires evaluation, and there you are. ... so the evaluation invokes undefined behavior. ...
    (comp.lang.c)
  • Re: Trap representations in the absence of padding bits
    ... and the current standard uses "lvalue" as the ... using "lvalue" to identify those expressions that are legal ... implies, a kind of *value*, and an rvalue is another kind of value. ... I'm used to thinking of the original "LVALUE" as a kind of evaluation ...
    (comp.lang.c)
  • Re: gcc: pointer to array
    ... any use as an lvalue will result in undefined behaviour. ... > be) an expression with an object type or an incomplete type ... Pray provide a reference. ... operator requires evaluation, and there you are. ...
    (comp.lang.c)