Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!usc!sdd.hp.com!spool.mu.edu!uunet!taumet!steve From: steve@taumet.com (Stephen Clamage) Newsgroups: comp.lang.c Subject: Re: Question on ANSI ## pre-processor operator. Message-ID: <729@taumet.com> Date: 15 May 91 15:34:15 GMT References: <28302040.69ED@deneva.sdd.trw.com> Organization: Taumetric Corporation, San Diego Lines: 56 knurlin@spf.trw.com (Scott Karlin) writes: >I am looking for a clarification on the ANSI-C token merging >operator (##). According to H&S: "After *all* [emphasis mine] >macro replacements have been done, the two tokens surrounding >any ## operator are combined into a single token." I interpret >this to mean that: >#define INDEX 0 >#define FN_NAME(x) name ## x >void FN_NAME(INDEX) () { printf("Hello\n"); } >Should expand to: >void name ## 0 () { printf("Hello\n"); } >And then: >void name0 () { printf("Hello\n"); } Not quite. Let's review. In the absence of any # or ## tokens in a macro replacement string, each macro parameter appearing in the replacement string is replaced by its fully-macro-expanded actual argument. Example #define INDEX 0 #define FN(x) fn x FN(INDEX) becomes fn 0 because the actual argument INDEX is fully expanded before it replaces the formal parameter x. When a macro parameter in the replacement string is preceded by # or preceded or followed by ##, the rule is different. The actual argument replaces the formal argument without any expansion, the # or ## operator is applied, then the resulting text is rescanned. This allows you to build up macro names for further replacement. Example: #define INDEX 0 #define FN(x) fn ## x FN(INDEX) becomes fn ## INDEX which becomes fnINDEX which cannot be further expanded. Your example will not work with the extra level of macro replacement. It can be used like this: #define FN_NAME(x) name ## x void FN_NAME(0) () { printf("Hello\n"); } which yields void name0 () { printf("Hello\n"); } -- Steve Clamage, TauMetric Corp, steve@taumet.com