[comp.lang.c] post-decrement quirk?

julbro@auto-trol.com (Julie Brown) (06/18/91)

Can anyone explain to me why the following does not work 
(at least on the Sun):

     q = q--;

'q' does not get decremented. No matter what the order of 
operations, I would expect 'q' to get decremented at some
point. It doesn't make a whole lot of sense to do this until 
you put it in a more meaningful context:


#include <stdio.h>
main()
{
   int count = 5;

   count = (count > 0) ? count-- : 0;
   printf("count %d\n", count);
}

the output from this program is :
      count 5 


pre-increment works just fine (q = --q;).

			just curious.

-- 
Julie Brown
julbro@auto-trol.COM                           Auto-trol Technology Corporation
{...}ncar!ico!auto-trol!julbro                 12500 North Washington Street
(303) 252-2856	                               Denver, CO 80241-2404

rgm@ocf.berkeley.edu (Rob Menke) (06/18/91)

In article <1991Jun17.230838.9628@auto-trol.com> julbro@auto-trol.com
(Julie Brown) writes:

   Can anyone explain to me why the following does not work 
   (at least on the Sun):

	q = q--;

It's quite simple:  set-value ('=') has a lower precedence than
post-decrement.  So, the expression on the RHS is evaluated (it equals
'q'), q is decremented, then q is set to the stored value from the
RHS.  Net result: no decrement.

You're better off with:
	q = (q > 0) ? q - 1 : 0;
--
"It is a pity that you Autobots die so	|  Robert Menke
 easily... otherwise one might get a	|    rgm@OCF.berkeley.edu
 sense of satisfaction..."		|    ...!ucbvax!OCF!rgm

worley@compass.com (Dale Worley) (06/18/91)

In article <1991Jun17.230838.9628@auto-trol.com> julbro@auto-trol.com (Julie Brown) writes:
   Can anyone explain to me why the following does not work 
   (at least on the Sun):
	q = q--;
   pre-increment works just fine (q = --q;).

According to Ansi C, neither of these is valid, because they both
modify q twice between two sequence points (during a statement).  The
fact that the second happens to do what you want it to is luck.

BTW, what *is* it that you want to do?  "q--" is equivalent to "q = q-1"
already, so you don't have to assign the result to q...

Dale Worley		Compass, Inc.			worley@compass.com
--
Start the project after the deadline -- the time pressure is less then.

steve@taumet.com (Stephen Clamage) (06/18/91)

rgm@ocf.berkeley.edu (Rob Menke) writes:

>In article <1991Jun17.230838.9628@auto-trol.com> julbro@auto-trol.com
>(Julie Brown) writes:

>   Can anyone explain to me why the following does not work 
>	q = q--;

>It's quite simple:  set-value ('=') has a lower precedence than
>post-decrement.  So, the expression on the RHS is evaluated (it equals
>'q'), q is decremented, then q is set to the stored value from the
>RHS.  Net result: no decrement.

This is not a correct explanation.  We have been through endless comments
on another thread, the evaluation of
	if( (i = 1) == (i = 2) )
and the situation here is the same.  In the expression
	q = q--
variable q is assigned a value in two places with no intervening sequence
point.  The result of the double assignment between sequence points is
undefined.  A compiler could reasonably evaluate the expression as if
you had written
	q = q; q--; 
or as if you had written
	tmp = q; q--; q = tmp;
In fact, since the result is specifically "undefined" (a technical term
in ANSI C), the compiler is free to do whatever it likes, such as send
you mail at run time telling you not to modify a variable twice between
sequence points.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

timr@gssc.UUCP (Tim Roberts) (06/19/91)

In article <RGM.91Jun17184532@avalanche.Berkeley.EDU> rgm@ocf.berkeley.edu (Rob Menke) writes:
>In article <1991Jun17.230838.9628@auto-trol.com> julbro@auto-trol.com
>(Julie Brown) writes:
>
>   Can anyone explain to me why the following does not work 
>   (at least on the Sun):
>
>	q = q--;
>
>It's quite simple:  set-value ('=') has a lower precedence than
>post-decrement.  So, the expression on the RHS is evaluated (it equals
>'q'), q is decremented, then q is set to the stored value from the
>RHS.  Net result: no decrement.

Although we need to be aware that this result is simply coincidence, and
some other compiler might produce different results.  Following the lengthy
and rather heated debate about the results of undefined statements in ANSI
C, I hope all you viewers out there at home recognized that the results of

	q = q--;

are UNDEFINED, because, like the statement which started this whole mess, this 
statement modifies a variable twice without an intervening sequence point. 

>You're better off with:
>	q = (q > 0) ? q - 1 : 0;

Correct.  The results of this are well-defined.
-- 
timr@gssc.gss.com	Tim N Roberts, CCP	Graphic Software Systems
						Beaverton, OR

This is a very long palindrome. .emordnilap gnol yrev a si sihT

Dave.Harris@f14.n15.z1.fidonet.org (Dave Harris) (06/20/91)

 >From: julbro@auto-trol.com (Julie Brown)

 >Can anyone explain to me why the following does not work 
 >(at least on the Sun):

 >     q = q--;

As I have been reminded several times in the last week myself, this statement 
is undefined.  Modifing an address multiple time between sequence points is 
undefined.  Both pre and post yeild 4 when I try this with what I use (TC++). 
Being undefined, your machine could yeild or do anything including crash on 
this statement (so I've been told).  q-- all by its lonesome self is 
sufficient.


 >'q' does not get decremented. No matter what the order of 
 >operations, I would expect 'q' to get decremented at some
 >point. It doesn't make a whole lot of sense to do this until 
 >you put it in a more meaningful context:

In machine language terms your compiler is possibly doing something like:

R1 = Q
Dec Q
Q = R1

where Q your variable and R1 is a register.  Just speculating of course.  
Fiddle with the optimizer switches and see if it acts differently.


 >#include <stdio.h>
 >main()
 >{
 >   int count = 5;

 >   count = (count > 0) ? count-- : 0;
 >   printf("count %d\n", count);
 >}

 >the output from this program is :
 >      count 5 

count = (count > 0) ? count-1 : 0;
count = max(0,count-1);
count -= (count>0);

no shortage of ways to do this.

 >pre-increment works just fine (q = --q;).

Dec Q
R1 = Q
Q = R1

Speculating again of course.
 


 

--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!15!14!Dave.Harris
Internet: Dave.Harris@f14.n15.z1.fidonet.org