Path: utzoo!utgpu!attcan!uunet!husc6!bloom-beacon!bu-cs!purdue!i.cc.purdue.edu!k.cc.purdue.edu!l.cc.purdue.edu!cik From: cik@l.cc.purdue.edu (Herman Rubin) Newsgroups: comp.lang.c Subject: Re: Unnecessary Macros (was Re: Unnecessary Parenthesis) Summary: We need local variables, obviously Message-ID: <956@l.cc.purdue.edu> Date: 29 Sep 88 14:58:18 GMT References: <2089@ssc-vax.UUCP> <441@kaon.uchicago.edu> <1401@devsys.oakhill.UUCP> <1851@loral.UUCP> Organization: Purdue University Statistics Department Lines: 59 In article <1851@loral.UUCP>, jlh@loral.UUCP (Physically Pffft) writes: < I was sure someone else would mention this so I didn't keep a copy of the < original article to quote. In general, someone is making a macro < to do z = x*x + y*y, but using a variable 'temp' to do it. I was under the < impression this was a Very Bad Idea for 2 reasons. Lets assume Mr C Wizard < has left the company 6 months ago and now it's up to Miss Molly to change < the code. First, she could use this power macro in a function that didn't < have the variable temp defined. No problem, the compiler spits out the < undefined variable. On the other hand, suppose she wants to put this macro < into a loop. She says to herself 'self, here's a variable temp that ain't used < here'. So we get < > for(temp = 0; temp < wanna_quit; temp++){ > z = power(x,y); > some_other_stuff; > } > > Well boys and girls, lets just hope this blows up in a way thats immediatly > obvious. As a third scenario, combine the first two scenarios. Poor Miss > Molly adds the power macro to a function that already has temp defined > and is definately needed. And lets say it's used in such a way that > her changes work fine and dandy, after all, she doesn't use temp in any > of her changes, but changes the original code in some insidious way. > Again, lets hope the result of changing temp is immediatly obvious. > > The moral? Well, if you have to use a temp variable in a macro then > PASS the bloody thing. > > #define power(x,y, tmp) (tmp = x*x + y*y, x = tmp) > > result = power(x, y, temp); > > This ensures that the poor overworked sucker who ends up maintaining your > code knows damn well that your macro requires a temp variable to work right. No, this doesn't necessarily work either. Suppose that this code is part of something else (a very likely situation) which uses a variable temp. Then the value of that variable is clobbered. What is needed is something like #define fc(x,y) (LOCAL tmp1,tmp2; tmp1=x; tmp2=y; fc(x,y)=tmp1*tmp1+tmp2*tmp2) which should be interpreted correctly even if x or y happens to be tmp1 or tmp2. That is, the LOCAL designation should provide a tag which separates the local variables from the rest, and disambiguates name collision. The user should not have to worry about whether the local designations in a block, or in a #define, etc. conflict with global. I believe that this also addresses the problem of code maintenance by someone other than the code writer. I do not know to what extent compiler implementations do this, but I doubt that a #define is treated other than a macro expansion, and I do not see how the problem can be avoided without something like this. -- Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907 Phone: (317)494-6054 hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)