knurlin@spf.trw.com (Scott Karlin) (05/15/91)
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"); } Which is what I want. However, two different ANSI (they say) compilers are not defining a function called "name0". Here is the actual code I used: /* ** example.c */ #include <stdio.h> #define PID 0 /* ** Token merging macro... */ #define FN_NAME(x) funct ## x /* ** Function prototypes... */ void main(void); void funct0(void); /* ** Simple main function. Nothing tricky here... */ void main() { funct0(); return; } /* ** I believe that this should get expanded by the pre-processor to ** funct0 () Note that I have intentionally placed a space between ** the macro "call" and the empty function parameter list. */ void FN_NAME(PID) () { printf("Hello, world.\n"); return; } Any information on the correct interpretation would be most welcome. -- Scott Karlin Internet: knurlin@spf.trw.com -- TRW Data Systems Center UUCP: ...!uunet!knurlin@spf.trw.com -- One Space Park, O2-1761 Phone: (213) 812-7335 -- Redondo Beach, CA 90278-1071 FAX: (213) 812-8800
vinoski@apollo.HP.COM (Stephen Vinoski) (05/15/91)
In article <28302040.69ED@deneva.sdd.trw.com> 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"); } (I have cross-posted this to comp.std.c since a similar question recently came up there. Follow-ups have been directed to comp.lang.c.) I had a problem with token pasting similar to yours. A compiler writer said that the problem was caused by the fact that I was attempting to paste arbitrary text with macro parameters; he said that token pasting is only meant to work on macro parameters. The ANSI C standard appears to agree with him; I believe it is section 3.8.3.3 (I don't have the standard handy) that says that ## causes macro parameters to be pasted together. If I have misinterpreted the standard, I'm sure I will hear about it. :-) I have also noticed that K&R II only shows macro parameters being pasted together. What if you change your example to: #define INDEX 0 #define REAL_FN_NAME(x,y) x ## y #define FN_NAME(x) REAL_FN_NAME(name,x) Then your example usage: >void FN_NAME(INDEX) () { printf("Hello\n"); } should produce the desired result. -steve | Steve Vinoski (508)256-0176 x5904 | Internet: vinoski@apollo.hp.com | | HP Apollo Division, Chelmsford, MA 01824 | UUCP: ...!apollo!vinoski |
steve@taumet.com (Stephen Clamage) (05/15/91)
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
vinoski@apollo.HP.COM (Stephen Vinoski) (05/16/91)
In article <519416cd.20b6d@apollo.HP.COM> vinoski@apollo.HP.COM (Stephen Vinoski) writes: >In article <28302040.69ED@deneva.sdd.trw.com> 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"); } > >I had a problem with token pasting similar to yours. A compiler >writer said that the problem was caused by the fact that I was >attempting to paste arbitrary text with macro parameters; he said that >token pasting is only meant to work on macro parameters. > >The ANSI C standard appears to agree with him; I believe it is section >3.8.3.3 (I don't have the standard handy) that says that ## causes >macro parameters to be pasted together. If I have misinterpreted the >standard, I'm sure I will hear about it. :-) Well, what do you know - I *did* misinterpret the standard. Sigh. Section 3.8.3.3 states that preprocessor tokens can be pasted together. The problem knurlin@spf.trw.com has is caused by the fact that token pasting occurs before the result is rescanned for further macro replacement. Thanks to steven@pacific.csl.uiuc.edu (Steven Parkes) for setting me straight on this one. I hereby promise not to quote the standard from memory again. -steve | Steve Vinoski (508)256-0176 x5904 | Internet: vinoski@apollo.hp.com | | HP Apollo Division, Chelmsford, MA 01824 | UUCP: ...!apollo!vinoski |