[comp.lang.c] Token Pasting

maart@cs.vu.nl (Maarten Litmaath) (12/03/88)

gwyn@smoke.BRL.MIL (Doug Gwyn ) writes:

\In article <6625@csli.STANFORD.EDU> wagner@arisia.xerox.com (Juergen Wagner)
\writes:
\>      proc/**/VERSION
\>People relying on this bug should change their habits. There are better ways
\>to concatenate tokens.

\No, for Reiser-based preprocessors there aren't any better ways.
\ANSI-style token pasting is fairly new, and many C implementations
\in current use do not support it.

Why didn't the ANSI committee legalize that current practice, instead of
defining a new paste operator (##)?
-- 
fcntl(fd, F_SETFL, FNDELAY):          |Maarten Litmaath @ VU Amsterdam:
      let's go weepin' in the corner! |maart@cs.vu.nl, mcvax!botter!maart

gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/04/88)

In article <1747@solo3.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>Why didn't the ANSI committee legalize that current practice, instead of
>defining a new paste operator (##)?

Because there were probably more C implementations that followed the
explicit rule stated in the base document (K&R 1st Ed.) than that
violated it.

Although X3J11 couldn't legalize this behavior, it did recognize the
utility of token pasting, which is why it designed a legal solution
to it.

I suggest adding a paste(a,b) macro to your equivalent of <std.h>,
and define paste(a,b) according to the specific implementation.  Be
advised that many pre-ANSI C implementations cannot implement this
macro.

henry@utzoo.uucp (Henry Spencer) (12/06/88)

In article <1747@solo3.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>Why didn't the ANSI committee legalize that current practice, instead of
>defining a new paste operator (##)?

Because that current practice was current practice only on some compilers;
on others it did not work and could not easily be implemented.  In
particular, it is hard to make it work under a token-based preprocessor.
It's also hard to define in a precise way that doesn't cause trouble with
other things.  (He who does not value a precise definition of this stuff
has never tried to implement it.)
-- 
SunOSish, adj:  requiring      |     Henry Spencer at U of Toronto Zoology
32-bit bug numbers.            | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

orr@cs.glasgow.ac.uk (Fraser Orr) (11/09/89)

I would like to define a cpp macro along the lines of

#define list(name,type) \
typedef _${name} { \
struct _${name} _${name}_Link \
${type} _${name}_Data } ${name} ;

(where I've emphasised where I want param expansion with ${...})
The problem is joining up the bits. "_name" does not expand, because it
is a whole token. Ideally what is required is something to join together
the tokens - perhaps PASTE(_,name). I seem to remember seeing this
somewhere but I've forgotten where. Any ideas? (e-mail => summary).


==Fraser Orr ( Dept C.S., Univ. Glasgow, Glasgow, G12 8QQ, UK)
UseNet: {uk}!cs.glasgow.ac.uk!orr       JANET: orr@uk.ac.glasgow.cs
ARPANet(preferred xAtlantic): orr%cs.glasgow.ac.uk@nsfnet-relay.ac.uk

hurwitz@enuxha.eas.asu.edu (Roger A. Hurwitz) (02/10/91)

I have heard about token pasting, and I have fooled around with
the C ## preprocessor operator, but I do not understand the
need for this capability.  Could someone provide an example
of when/where/how token pasting comes in handy?

Thanks,
Roger Hurwitz
hurwitz@enuxha.eas.asu.edu

bliss@sp64.csrd.uiuc.edu (Brian Bliss) (02/12/91)

In article <2261@enuxha.eas.asu.edu>, hurwitz@enuxha.eas.asu.edu (Roger
A. Hurwitz) writes:
|> 
|> I have heard about token pasting, and I have fooled around with
|> the C ## preprocessor operator, but I do not understand the
|> need for this capability.  Could someone provide an example
|> of when/where/how token pasting comes in handy?
|> 
|> Thanks,
|> Roger Hurwitz
|> hurwitz@enuxha.eas.asu.edu

 The last time I needed to do it was when writing a debugger.
 For each simple type, I had an associated type descriptor and 
 symbol. so I needed to say:

 #define init(keyword)	keyword ## _symbol = \
                           symbol_alloc ("keyword", keyword ## _type) 

 init (int)
 init (short)
 init (long)

  etc.

 when I tried to port the thing, the token pasting didn't work,
 putting a macro argument inside a string didn't result in
 the correct substitution, etc., so I gave up and hard-coded
 the whole damn thing.

 bb

sanders@peyote.cactus.org (Tony Sanders) (02/12/91)

In article <1991Feb11.195439.17787@csrd.uiuc.edu> bliss@sp64.csrd.uiuc.edu (Brian Bliss) writes:
> #define init(keyword)	keyword ## _symbol = \
>                           symbol_alloc ("keyword", keyword ## _type) 
should be:

#ifdef __STDC__
#define init(keyword)	keyword ## _symbol = \
                          symbol_alloc (# keyword, keyword ## _type) 
#else
#define init(keyword)	keyword ## _symbol = \
                          symbol_alloc ("keyword", keyword ## _type) 
#endif

Which I use like this:

#ifdef __STDC__
#define DPV(variable,type)   if (debug) fprintf(stderr, \
    "%s:%d, " # variable " = %" # type "\n",__FILE__,__LINE__,variable)
#else
#define DPV(variable,type)   if (debug) fprintf(stderr, \
    "%s:%d, variable = %type\n",__FILE__,__LINE__,variable)
#endif

It's quite ugly but it works great.  Your mileage may vary.
This works because # keyword converts to "expaned_keyword"
and "foo" "bar" "bat" "baz" converts to "foobatbatbaz".

-- sanders@peyote.cactus.org
First rule of software:  Throw the first one away.
and so on...
I am not an IBM representative and I speak only for myself.