[comp.unix.questions] Preprocessor Usage Question

terryb.bbs@shark.cs.fau.edu (terry bohning) (04/25/91)

Here is a preprocessor question:
I want to define a macro which will put either "a_" or 
"b_" in front of all my function names.  Can it be done.
That is, something like:

#define RADIO a         /* #define RADIO a or b */

main() {
        RADIO_func1(args);
        RADIO_func2(args);
        .
        .
}

Of course, this doesn't work, but I think you see what I would like
to do.

thanx
tb

weimer@garden.ssd.kodak.com (Gary Weimer (253-7796)) (04/26/91)

In article <R7NX11w163w@shark.cs.fau.edu>, terryb.bbs@shark.cs.fau.edu
(terry bohning) writes:
|> Here is a preprocessor question:
|> I want to define a macro which will put either "a_" or 
|> "b_" in front of all my function names.  Can it be done.
|> That is, something like:
|> 
|> #define RADIO a         /* #define RADIO a or b */
|> 
|> main() {
|>         RADIO_func1(args);
|>         RADIO_func2(args);
|>         .
|>         .
|> }
|> 
|> Of course, this doesn't work, but I think you see what I would like
|> to do.

Two ways you COULD do it (may or may not be protable, use at your own
risk, etc, etc,...):

EXAMPLE 1
1>
1>#define RADIO(x)	a_/**/x
1>
1>main() {
1>	RADIO(func1)(args);
1>	RADIO(func2)(args);
1>	.
1>	.
1>}

EXAMPLE 2
2>
2)#define RADIO		a
2>
2>main() {
2>	RADIO/**/_func1(args);
2>	RADIO/**/_func2(args);
2>	.
2>	.
2>}

These work (on my system--SunOS) because the preprocessor treats
comments as delimiters and then removes them. This would not work if:

1) The preprocessor replaced comments with white space
2) The preprocessor did not remove comments, and the compiler treated
   them as delimiters or substituted white space.
3) Your preprocessor was released on the second tuesday after the first
   full moon from one month before Mercury reached its zenith in ...

weimer@ssd.kodak.com ( Gary Weimer )

jik@athena.mit.edu (Jonathan I. Kamens) (04/26/91)

  Many pre-ANSI-C preprocessors will let you use /**/ to do concatenation as
Gary Weimer has described.  Some ANSI-C preprocessors will let you do it too,
but it's the WRONG way to do it with an ANSI-C preprocessor; under ANSI C, you
should use the ## macro operator.

  I took the following source file:

	#define R1(x) a_/**/x
	#define R2(x) a_##x
	#define R3 a_

	R1(func1)(args);
	R2(func1)(args);
	R3/**/func1(args);
	R3##func1(args);

And fed it into 4.3BSD's preprocessor, and got out this (blank lines and #
line number directives deleted):

	 a_func1(args);
	 a_##func1(args);
	a_func1(args);
	a_##func1(args);
	pit-manager% cc -E -Hnocpp test.c

So, under 4.3BSD, the /**/ trick works, and ANSI C's ## doesn't.  Then, I took
the same file and fed it into High C's internal ANSI-C preprocessor, which
resulted in:

	a_ func1 (args);
	a_func1  (args);
	a_    func1(args);
	a_##func1(args);

Note first of all that the /**/ DIDN'T work, because extra blank space was
left where the /**/ appeared.  This is perfectly permissible according to the
ANSI C specification.  The ## operator worked, but only when it was used
inside a macro, since that's when it's supposed to work.

  I guess the summary of all this is that something like this

	#ifdef __STDC__
	#define RADIO(x) a_##x
	#else
	#define RADIO(x) a_/**/x
	#endif

is the best you can do.

-- 
Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8085			      Home: 617-782-0710

jim@segue.segue.com (Jim Balter) (04/30/91)

In article <1991Apr25.234340.22311@athena.mit.edu> jik@athena.mit.edu (Jonathan I. Kamens) writes:
>  I guess the summary of all this is that something like this
>
>	#ifdef __STDC__
>	#define RADIO(x) a_##x
>	#else
>	#define RADIO(x) a_/**/x
>	#endif
>
>is the best you can do.

Actually

#ifdef __STDC__
#define RADIO(x) a_##x
#else
#define IDENT(x)x
#define RADIO(x) IDENT(a_)x
#endif

is better, because it works for more cpp's.  It could fail
for a non-ANSI cpp that has ANSI-style tokenization.
The IDRIS (the what?) cpp might fit that bill.