[comp.lang.c] Macro Problem

gateley@mips.csc.ti.com (John Gateley) (09/26/88)

Tried to send mail, but it died.

In article <23@datcon.UUCP> sar@datcon.co.uk (Simon A Reap) writes:
[edited]
>>>   #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));
[explanation of how moving the subexpressions around cause z = y^4]
>Does anyone know how to get round this problem?  Please!!

Hi Simon:

Try
#define square(x,temp) (temp = (x),(temp * temp))
Then z = square(x,t1) + square(y,t2) expands into
z = (t1 = (x),(t1 * t1)) + (t2 = (y),(t2 * t2))
which will give you the desired behavior. I am not sure that this will
really work, as I don't program in C, just Lisp/Scheme.

This problem is known as the capturing problem and is well documented in
the Lisp community. There are three solutions:
1) Use uncommon variable names (which is sort of what I did above). This
   is not a real solution.
2) Make the macro expand things in the proper scope. This requires first
   class functions closed over lexical environments, and so is not really
   appropriate for C.
3) Make the macro expander smart about the language, so that it automatically
   generates unique names for macro generated lexical variables. Again, this
   is not appropriate for C.
Check some of the literature on Lisp/Scheme macro expansion if you are
interested.

Hope this helps,
John Gateley
gateley@mips.csc.ti.com