Re: [C, C++] "(a=b) = c;" Illegal or Undefined?

From: Arthur J. O'Dwyer (ajo_at_nospam.andrew.cmu.edu)
Date: 01/27/04


Date: Tue, 27 Jan 2004 16:57:15 -0500 (EST)


On Tue, 27 Jan 2004, Jerry Coffin wrote:
>
> Arthur O'Dwyer <ajo@nospam.andrew.cmu.edu> says...
> [ given: ]
> > > > char *f(char *p, char c) { *p=c; return p; }
> > > >
> > > > char buf[5];
> > > > char *p=buf;
> > > >
> > > > *(f(*p, 'A'))='B';
> [ ... ]
> > The sequence points are:
> > One after the evaluation of f, p and 'A', but before the call to f
> > One at the semicolon ending the statement *p = c;
> > One at the semicolon ending the statement return p;
> > One at the semicolon ending the statement *(f(p,'A'))='B';
>
> We have NONE that determines the order of evaluation between the two
> assignments.

  Yes, we do. The first assignment "*p = c;" happens *before* the
return from f', and the second assignment "*(...)='B';" happens
*after* the return from 'f'.
  The assignments happen in chronological order, which is a linear
ordering on the set of events that happen. Since the first assignment
happens before "return p;", and "return p;" happens before the second
assignment, we may conclude (from the transitivity property of linear
orderings) that the first assignment happens before the second
assignment. Q.E.D.

> > Thus we have, in this order:
> > Call f.
> > Assign 'A' to *p.
> > Return p.
> > Assign 'B' to *p.
> >
> > All perfectly well-defined, in both languages.
>
> OR we have:
>
> assign 'B' to *p
> call f

  No, this ordering is patently impossible. You might as well say
that we could have

  assign 'B' to *p
  assign 'A' to *p
  call f

The Standard explicitly tells us where the sequence points in this
code are, and those sequence points prohibit your hypothetical
implementation from re-arranging the code in these ways.

> The sequence points are enough to determine that, in essence, the
> assignment operator (or any other function) runs atomically.

  The C Standard does not define "atomically" except in the context
of operations on sig_atomic_t, which is fairly obscure and IMHO
not relevant to this discussion. <OT> And no, it's perfectly possible
for an assignment operation (e.g., a structure assignment) to be
interrupted by a signal or interrupt on all systems with which I
am familiar. </OT>

> They are
> not enough to determine the order in which the two assignments are
> evaluated.

  Yes, they are. That's what sequence points *do* -- they impose
sequence on a set of events in the program. Are you *surprised* that
the Standard requires this code to behave in the expected fashion? :-/

-Arthur



Relevant Pages

  • Re: x=(x=5,11)
    ... convert it to the type of the assignment expression without evaluting ... Sequence points define a partial ordering. ... "The order of evaluation of the function designator, ... made to modify the result of a comma operator or to access it after the ...
    (comp.lang.c)
  • Re: Must an expression be evaluated before its value is used?
    ... I think that is a poor example because the compiler is allowed to ... It is actually implied by the semantics of the assignment expression. ... on when the side-effects of that evaluation are to occur. ... sequence point is implied. ...
    (comp.std.c)
  • Re: x=(x=5,11)
    ... You're introducing a sequence point between the right-hand side of the ... assignment operator and the assignment itself. ... define such a sequence point between the evaluation of the arguments to ... the value of the right operand is converted ...
    (comp.lang.c)
  • Re: Strange operands to conditional operator
    ... has higher precedence than an assignment operator, ... order of evaluation. ... There is a sequence point after the first operand. ...
    (comp.lang.c)
  • Re: Must an expression be evaluated before its value is used?
    ... this is not a sequence point. ... The evaluation dependency has a consequence of ... seperate the assignment of 5 to x from the assignment of 11 to x. ... comma operator without first evaluating it's second operand. ...
    (comp.std.c)