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