[comp.lang.c] Order of evalution of expressions.

elee24@castle.ed.ac.uk (H Bruce) (09/18/90)

I have lost my FAQ files but I'm certain this is not on it....

Is the line

value = *ptr - *ptr++;

sensible C ?
In other words is there a specified order of evaluation of expressions ?
If not then the answer would depend on when the increment is done.

If not what is the fastest way of computing this type of expression ?
Would the following lines be optimized by a compiler (so that value is
not loaded twice) ?

value = *ptr;
value -= *ptr++;


Thanks,

Henry Bruce.

flaps@dgp.toronto.edu (Alan J Rosenthal) (09/19/90)

elee24@castle.ed.ac.uk (H Bruce) writes:
>Is the line
>
>value = *ptr - *ptr++;
>
>sensible C ?

absolutely not.

>Would the following lines be optimized by a compiler (so that value is
>not loaded twice) ?
>
>value = *ptr;
>value -= *ptr++;

quite often, but no non-machine-specific language definition can guarantee you
that.  but they're the best.

cudcv@warwick.ac.uk (Rob McMahon) (09/19/90)

In article <6398@castle.ed.ac.uk> elee24@castle.ed.ac.uk (H Bruce) writes:
>Is the line
>
>value = *ptr - *ptr++;
>
>sensible C ?
>In other words is there a specified order of evaluation of expressions ?

Absolutely not, no.

>Would the following lines be optimized by a compiler (so that value is
>not loaded twice) ?
>
>value = *ptr;
>value -= *ptr++;

Well, gcc optimizes this to

	ptr++;
	value = 0;

I suspect your code may be wrong :-)

Rob
--
UUCP:   ...!mcsun!ukc!warwick!cudcv	PHONE:  +44 203 523037
JANET:  cudcv@uk.ac.warwick             INET:   cudcv@warwick.ac.uk
Rob McMahon, Computing Services, Warwick University, Coventry CV4 7AL, England

lfd@cbnewsm.att.com (leland.f.derbenwick) (09/19/90)

In article <6398@castle.ed.ac.uk>, elee24@castle.ed.ac.uk (H Bruce) writes:
> I have lost my FAQ files but I'm certain this is not on it....
> 
> Is the line
> 
> value = *ptr - *ptr++;
> 
> sensible C ?
> In other words is there a specified order of evaluation of expressions ?

Not in this case.

> If not then the answer would depend on when the increment is done.
> 
> If not what is the fastest way of computing this type of expression ?

Assuming ptr does not point to a volatile value (e.g., a hardware
status register), then there's a trivial optimization:

  value = 0;  ptr++;

If it really requires two reads of *ptr, then the order of the reads
is also important, and your other approach should be taken:

> value = *ptr;
> value -= *ptr++;

Note that

  value = *ptr - *ptr;  ptr++;

is _not_ equivalent, since there is no guarantee which "*ptr" access
is done first: this could give either the initial value minus the
final value, or the final value minus the initial value.

Also, if the value being read is volatile, it must be declared so
(in ANSI-compatible compilers) or optimization must be turned off
(in older compilers).  Some compilers won't optimize the two reads
of *ptr away anyhow, but it's extremely risky to assume that.

 -- Speaking strictly for myself,
 --   Lee Derbenwick, AT&T Bell Laboratories, Warren, NJ
 --   lfd@cbnewsm.ATT.COM  or  <wherever>!att!cbnewsm!lfd

darcy@druid.uucp (D'Arcy J.M. Cain) (09/20/90)

In article <6398@castle.ed.ac.uk> elee24@castle.ed.ac.uk (H Bruce) writes:
>I have lost my FAQ files but I'm certain this is not on it....
>Is the line
>value = *ptr - *ptr++;
>sensible C ?
> ...
>If not what is the fastest way of computing this type of expression ?
>Would the following lines be optimized by a compiler (so that value is
>not loaded twice) ?
>
>value = *ptr;
>value -= *ptr++;
Why not:
    value = 0;
	ptr++;

I suppose you meant:
	value = *ptr;
	value -= *(++ptr);
or
	value = *ptr++;
	value -= *ptr;

In any case, the order of evaluation is undefined (K&R2 pp 53) so you
you need two statements.

-- 
D'Arcy J.M. Cain (darcy@druid)     |
D'Arcy Cain Consulting             |   MS-DOS:  The Andrew Dice Clay
West Hill, Ontario, Canada         |   of operating systems.
+ 416 281 6094                     |

bruce@seismo.gps.caltech.edu (Bruce Worden) (09/25/90)

In article <6398@castle.ed.ac.uk> elee24@castle.ed.ac.uk (H Bruce) writes:
>Is the line
>
>value = *ptr - *ptr++;
>
>sensible C ?

As others have pointed out, it is not; the behavior is undefined and
therefore may be implementation dependent.  

>If not what is the fastest way of computing this type of expression ?
>Would the following lines be optimized by a compiler (so that value is
>not loaded twice) ?
>value = *ptr;
>value -= *ptr++;

Remember, the increment takes place after the value is used, so you are
effectively subtracting *ptr from itself.  I suspect that what you want 
to do is:

	value = ptr[0] - ptr[1];
	ptr++;

As was discussed here a couple of weeks ago, this form should be as
efficient as the form:

	value = *ptr - *(ptr+1);
	ptr++;

The first form is, I think, clearer.
--------------------------------------------------------------------------
C. Bruce Worden                            bruce@seismo.gps.caltech.edu
252-21 Seismological Laboratory, Caltech, Pasadena, CA 91125