Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watmath!orchid!jagardner From: jagardner@orchid.UUCP Newsgroups: comp.lang.c Subject: Re: ANS C Macro Processing Message-ID: <11322@orchid.waterloo.edu> Date: Thu, 22-Oct-87 18:49:07 EDT Article-I.D.: orchid.11322 Posted: Thu Oct 22 18:49:07 1987 Date-Received: Sat, 24-Oct-87 14:36:28 EDT References: <167@sdti.UUCP> Reply-To: datanguay@watbun.waterloo.edu (David Tanguay) Organization: U. of Waterloo, Ontario Lines: 59 Wow! I was just about to post a similar article! The example I've been toying with is: #define f(a) a+g #define g(a) f(a) f(1)(2) The expansion follows as: "f(1)(2)" -> "1+g(2)" -> "1+f(2)" Do I now expand f or not? I currently thinking of not. But consider the following (with above definitions): f(1)(2)(3)(4)(5)(6) If I do re-expand f, this leads to "1+2+3+4+5+6+g", which is kind of neat-o. To prevent the re-expansion, I put a special token into the token sequence following the replacement list of f. When I start processing the replacement list of f, I turn f off, and then don't turn it on again until I see that special token (basically, it says "turn f back on" - it could also say "turn g back on" and so forth). The catch is that the routine that expands macros does not trigger these special tokens, it moves them to the end of replacement. So with my special token represented as # followed by the name of the macro to turn back on (eg #f), the replacement looks like: f(1)(2) replace f(1) => 1 + g #f /* f now turned off */ rescan: 1 + g #f ( 2 ) I see g, and that it is a valid macro name, so I call the replacement routine on g. The replacement routine sees the #f token, remembers it but does not activate it yet. Therefore it sees 1 + g ( 2 ) replace g(2) => 1 + f(2) #g /* g now turned off */ append the #f to get 1 + f(2) #g #f rescan: 1 + f(2) #g #f f is off, so we get 1 + f ( 2 ) see the #g, so turn g back on see the #f so turn f back on When I asked co-workers, 2 said the expansion should be "1+2+g", and 1 said "1+f(2)". I thought "1+f(2)" because the phrase in the standard "the resulting preprocessing sequence is rescanned with the rest of the source file's preprocessing tokens" (section 3.8.3.4) vaguely suggests that this is the case, but I think the wording should be made clear. Another not well defined point has to do with the ## CPP operator. #define g(a) #a #define f(a,b) g(#a ## #b) f(hi,there) Is the resulting C string "\"hi\"\"there\"" or "hithere"? I.e., what does it mean to ## 2 strings? The phases of translation says that string concatenation by adjacency comes after macro expansion, so it's a question of whether ## should join the 2 strings. I favour it joining the strings because you can have them not joined by just saying #define f(a,b) g(#a #b) although this results in an extra space in the final expansion of g. David Tanguay, Software Development Group, University of Waterloo