Unnecessary Macros (was Re: Unnecessary Parenthesis)

Herman Rubin cik at l.cc.purdue.edu
Fri Sep 30 00:58:18 AEST 1988


In article <1851 at loral.UUCP>, jlh at 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 at l.cc.purdue.edu (Internet, bitnet, UUCP)



More information about the Comp.lang.c mailing list