use of if (!cptr) and if (cptr) && a programming error
Andrew Koenig
ark at alice.UUCP
Sat Jul 22 15:01:48 AEST 1989
In article <2990 at nmtsun.nmt.edu>, dwho at nmtsun.nmt.edu (David Olix) writes:
> [Skipping all the "In article..." stuff]
> >[Material everybody has seen n times deleted.]
> >I am kind of butting in [ :-) ], but how 'bout
> > while ( ( myptr = my_func() )->x != myptr->y )
> > {
> > }
>
> >THAT WILL NOT WORK! [...]
>
> Actually, "Mastering C" by Craig Bolon, SYBEX Inc., p. 273 says that
> parenthesis operators have the HIGHEST priority, therefore what's inside
> (myptr = my_func()) would get evaluated first. Also, it specifies that
> grouping for the '!=' operator is from left to right. Now, the author of
> this book may have been wrong.... Anyone seen an "official" statement
> from K&R?
I might as well put my two cents in.
Precedence and order of evaluation are two different things.
Precedence has to do with deciding what sub-expression is the
operand of each operator. For example, the precedence rules of
C say that
a != b != c
is equivalent to
(a != b) != c
and is not equivalent to
a != (b != c)
However, nowhere does C make any guarantee about the order in
which a, b, and c will be fetched. It is completely legal for
a C compiler to evaluate
a != b != c
by the following sequence of operations:
copy b into register 1
copy c into register 2
copy a into register 3
compare registers 1 and 3 and put the result into register 0
compare registers 0 and 2
Similarly, in the expression
( myptr = my_func() )->x != myptr->y
there is no doubt that the two things being compared are
( myptr = my_func() )->x
and
myptr->y
However, the compiler is under no obligation to evaluate these
two sub-expressions in any particular sequence. Only in the case
of && || , and ?: operators does the compiler incur any such
obligation. Thus, this expression could be rewritten:
( ( myptr = my_func() ), ( myptr->x != myptr->y ) )
to guarantee that the value of `myptr' used in the comparison
would always be that returned by my_func(). Moreover, the
precedence rules (not order of evaluation) allow the expression
to be simplified slightly:
( myptr = my_func(), myptr->x != myptr->y )
with precisely the same effect.
Finally, note that commas that separate function arguments
are not comma operators. In this expression:
my_other_func ( myptr = my_func(), myptr->x != myptr->y )
there is no guarantee of whether myptr is assigned before or
after it is used to fetch the values of myptr->x and myptr->y.
For such a guarantee, one would have to write
myptr = my_func(), my_other_func ( myptr, myptr->x != myptr->y )
--
--Andrew Koenig
ark at europa.att.com
More information about the Comp.lang.c
mailing list