Concatenating with a compile-time definition in "ANSI" CPP

Jim Hunt hunt at ernie.Berkeley.EDU
Tue Oct 3 16:32:48 AEST 1989


In article <29351 at watmath.waterloo.edu> datanguay at watmath.waterloo.edu (David Adrien Tanguay) writes:
>In article <470004 at gore.com> jacob at gore.com (Jacob Gore) writes:
>>Can the following be achieved with "ANSI" cpp:
>>	MtaInit()
>>expands to
>>	SomeNameInit()
>>where Mta=SomeName is specified at compile-time, WITHOUT enumerating every
>>possible value of Mta in an #ifdef?
>
>#define join(a,b)  a ## b
>#define join2(a,b) join( a, b )
>#define MtaInit    join2( Mta, Init )
>David Tanguay

You can do this in non ANSI environments (at least Sun) with
#define MyInit(arg)   arg/**/Init
which is an ugly hack on the preprocessor, that is also defined
in the ANSI C preprocessor!  I had no idea what the silly ##
operator was for until I came up with the following.  I had the
desire to be able to say p=NewNodetype1() or q=NewNodetype2()
without having to separately define all of the NewNodetype?()
functions.  My memory of this has faded, but....
(The NodeType* were defined elsewhere in some .h)
nodes.c contained many loops of:

#define magic(arg) arg/**/NodeType1 /* or use ## if ANSI */
#include x.c

along with suitable #undefs
and x.c contained

magic()* magic(LOAS) = (magic()*)0;
magic()* magic(New)() { if (magic(LOAS)==(magic()*)0) ( ... }
/* work this through three times, different ways, before flaming! */
/* yes, lint complained about arg counts */

This allowed me to have one file of routines to handle the LOAS
(list of available space), New, and Free routines, that was
expanded to the names I wanted.  I did NOT want to have to call
from an array of functions, or have other weird ways to deal with
this.  The many News and Frees done this way did take up all the
space of many copies, but were perfect for a development
environment where the node types changed from day to day.  (I
would not consider releasing code done this way.)  They also
supported counters (magic(OUT) & magic(FREED)) so I could keep
track of node usage too.  The great part was that x.c was only 33
lines long, including the page-at-a-time allocation for garbage
collection support.  I sweated til I was absolutly SURE of those
33 lines, but then I used them many times.  I argue that it is
easier to be perfect for 33 lines than over many copies, or some
complicated array of functions, or generic routines that you end
up changing every other day, or ...

:-) if I really thought this was a good idea, would I be trying
so hard to defend it?!?  I used it, it was cute, but......

Is this what the ## operator is for???  If not, what IS it for?

jim hunt at ernie.Berkeley.EDU	H&H Enterprises
These ARE the bosses opinions, I AM the * boss!!!
grad UCB, MS EE/CS, May 90, resume on request.
Newsgroups: comp.lang.c
Subject: Re: Concatenating with a compile-time definition in "ANSI" CPP
Summary: 
Expires: 



More information about the Comp.lang.c mailing list