Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!bloom-beacon!apple!bionet!ig!agate!ucbvax!decwrl!sun!pitstop!sundc!seismo!uunet!mcvax!ukc!pyrltd!datcon!sar
From: sar@datcon.UUCP (Simon A Reap)
Newsgroups: comp.lang.c
Subject: Re: Unnecessary Parenthesis
Summary: be careful with temporary variables in macro expansions
Keywords: Use 'em all the time in macros...
Message-ID: <23@datcon.UUCP>
Date: 23 Sep 88 15:15:36 GMT
References: <2089@ssc-vax.UUCP> <441@kaon.uchicago.edu> <1401@devsys.oakhill.UUCP>
Reply-To: sar@datcon.co.uk (Simon A Reap)
Organization: Data Connection Limited
Lines: 31

(old discussion, but our News was gebustenbroken for yonks)
In article <1401@devsys.oakhill.UUCP> steve@oakhill.UUCP (steve) writes three
alternatives for the square(x) macro:

>>   #define square(x)    (x * x)
>>   #define square(x)    ((x) * (x))
>>   #define square(x)    (temp = (x),(temp * temp))
>
Please note, the third version is *dangerous*.  An expression such as:

    z = square(x) + square(y);

expands to:

    z = (temp = (x),(temp * temp)) + (temp = (y),(temp * temp));

which looks OK, but note that, although C guarantees to perform the
assignment (temp = (x)) before the multiplication (temp * temp) in each
expansion of square(x), but it does *not* guarantee to complete the
first expansion before it starts the second (or vice versa).  I have
seen at least 2 compilers which do the first assignment, then the second
assignment (to the same 'temp' variable), followed by the 2 multi-
plications, so you end up with the same value of 'temp' squared twice.

Does anyone know how to get round this problem?  Please!!
(it's been bugging us for months :-( )

-- 
Enjoy,
yerluvinunclesimon                Opinions are mine - I don't even have a cat
Reach me at sar@datcon.co.uk, or ...!mcvax!ukc!pyrltd!datcon!sar