[net.lang.c] 'op=' operators

nowlin@ihu1e.UUCP (Jerry Nowlin) (10/03/84)

<.>

 > I am not sure how K&R specify that
 >      *ptr++ += 2;
 > should be evaluated. Page 191 says only that the behaviour of E1 op= E2
 > is the same as E1 = E1 op E2, but does that mean in this case
 >      *ptr++ += *ptr++ + 2;
 >      *ptr += *ptr++ + 2;
 > or
 >      *ptr++ += *ptr + 2; ? (and what does the first form mean?)
 >
 > For out 4.2 bsd compiler, the last form is used, with the incrementation of
 > the pointer after the addition of 2. Is this guaranteed by the standard?
 >               Robert

(I hope you meant to use = instead of += in your attempts at clarification.)

Excuse me, but this article reminds me of "Old McDonald Had a Farm."

     With a ++ here, and a ++ there.
     Here a +.  There a +.
     Everywhere a ++.

I think there should be a rule of style that says "If you can't figure out
what a statement will do without trying it, rewrite it!" How about scanning:

     *ptr += 2;
     ptr++;

Does anybody have a shred of doubt what that will do?  If so try this:

     *ptr = *ptr + 2;
     ptr = ptr + 1;

I certainly wouldn't go as far as the last example to make my code readable,
but the "experts" that think up these clever little statements that take
longer to decipher (six months down the road when one of them backfires) than
rewriting the entire program should be forced to use COBOL for the rest of
their lives!

Jerry Nowlin
ihnp4!ihu1e!nowlin

pcf@drux3.UUCP (10/04/84)

> I am not sure how K&R specify that
>      *ptr++ += 2;
> should be evaluated. Page 191 says only that the behaviour of E1 op= E2
> is the same as E1 = E1 op E2, ...
>               Robert

Are you sitting comfortably, then I'll begin. Once upon a time...
Some quotes from the good book:	(K&R 'C')

Page 187
   When postfix ++ is applied to an lvalue the result is the value of the
object referred to by the lvalue. After the result is noted, the object is
incremented in the same manner as for the prefix ++ operator.

Page 191:
   The behavior of an expression of the form E1 op= E2 may be inferred by tak-
 ing it as eqivalent to E1 = E1 op (E2); however, E1 is only evaluated once.

We now have enough information to work it out.
      *ptr++ += 2;

The expression on the right is evaluated (once),
	E1 = *ptr++;

its value is the thing pointed to before the increment (*ptr). This value is
then (effectively) substituted in the expression
	E1 = E1 + (2);

	*ptr = *ptr + 2; ptr++;

Easy.

Now the encore:

Page 185:
   ...the order of evaluation of expressions is undefined. In particular the
compiler considers itself free to compute subexpressions in the order it
believes most efficient, even if the subexpressions involve side effects.

And remember that assignment operators are just operators, this means that
	*ptr++  =  *ptr++ + 2;
	*ptr    =  *ptr++ + 2;
	*ptr++  =  *ptr++ + 2;

are all wrong. Correct versions include:

	*ptr++ += 2;
	*ptr += 2; ptr++;

Peter C. Fry
drux3!pcf