Subject: Re: small hack
To: Andrew Brown <twofsonet@graffiti.com>
From: Alan Barrett <apb@iafrica.com>
List: tech-userlevel
Date: 09/23/1998 17:06:30
On Wed, 23 Sep 1998, Andrew Brown wrote:
> and if you were feeling short on storage, or just obscure, you could
> always replace the three assigments with the temporary with either
> 
> 	shuffle[j]^=shuffle[i]^=shuffle[j]^=shuffle[i];
> 
> which would be fine, since you're using integers,

No, that violates the rule about "thou shalt not attempt to modify
anything more than once without an intervening sequence point", or more
precisely:

         Between the previous and next sequence point, an object shall
         have its stored value modified at most once by the evaluation
         of an expression.  Furthermore, the prior value shall be
         accessed only to determine the value to be stored.
		[ANSI/ISO 9899-1990 section 6.3, page 38]

You are trying to modify shuffle[i] twice, and you are also trying to
modify shuffle[j] twice.

Even if you make that problem go away by adding some sequence points,
thus:

	shuffle[j]^=shuffle[i];
	shuffle[i]^=shuffle[j];
	shuffle[j]^=shuffle[i];

you still have the problem that, when i==j, the above code sets both
shuffle[i] and shuffle[j] to zero.

> or, if you decide
> you want something that's non-type specific (ie, work with floats
> too), you'd have to use
> 
> 	shuffle[i]=-(shuffle[i]-=shuffle[j])+(shuffle[j]+=shuffle[i]);
> 
> but that'd just be silly.  :)

That still has the sequence point problem, and this time it can't be
fixed without a temporary variable.  It also has overflow and loss of
precision problems.

--apb (Alan Barrett)