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