[comp.lang.c] Problem with strange macro definition

root@libove.UUCP (Jay M. Libove) (01/22/89)

System: SCO Xenix 286 v2.2.1 (roughly System V release 2 Unix) on a
PCs Limited 286 box; SCO Xenix 286 v2.2.1 development system as well.

I am trying to build a huge software package that includes something
like this:

#define awful_macro(nnnn) \
 if (x_/**/nnnn > y_/**/nnnn) z_/**/nnnn = 0

Which causes the SCO compiler to generate errors claiming that
x_nnnn y_nnnn and z_nnnn are undefined variables in the source module.

I know that it is a long standing and not-likely-to-be-corrected bug
in the generic 'pcc' compiler that makes x_/**/nnnn evaluate to x_nnnn
instead of the x_ nnnn that the language definition calls for it to be,
and I can only assume that the authors of this gross code intended for
macro substitution to take place on the nnnn part, achieving the effect
of passing multiple variables via one name... but anyway it certainly
doesn't work.

Can someone suggest what to do to get around this?

Thanks in advance!
-- 
Jay Libove		ARPA:	jl42@andrew.cmu.edu or libove@cs.cmu.edu
5731 Centre Ave, Apt 3	BITnet:	jl42@andrew or jl42@drycas
Pittsburgh, PA 15206	UUCP:	uunet!nfsun!libove!libove or
(412) 362-8983		UUCP:	psuvax1!pitt!darth!libove!libove

rbutterworth@watmath.waterloo.edu (Ray Butterworth) (01/26/89)

In article <208@libove.UUCP>, root@libove.UUCP (Jay M. Libove) writes:
> #define awful_macro(nnnn) \
>  if (x_/**/nnnn > y_/**/nnnn) z_/**/nnnn = 0
> Which causes the SCO compiler to generate errors claiming that

The trick is to put the token joining into yet another macro,
and then to use that macro in any of your own macros.
Then whenever you move to a new compiler, you need only add
more conditions to the one place to make all the other macros
work properly (if it is possible that is).

Note that the absence of spaces after commas is not simply
a matter of style.

This should work on pANS, gnu, and Reiser cpp's:

/* this part should be in a header included by all your other headers */
#if !defined(__STDC__)
#   define __GLUE(x)x
#   define GLUE(a,b) __GLUE(a)b
#   define QUOTE(x) "x"
#else  /* __STDC__ */
#   define __JOIN(x)x##
#   define GLUE(a,b) a##b
#   define QUOTE(x) #x
#endif/* __STDC__ */

/* this part should be in your header file defining the awful_macro */
#define awful_macro(nnnn) \
    if (GLUE(x_,nnnn) > GLUE(y_,nnnn)) GLUE(z_,nnnn) = 0

/* this part should be in your source file */
awful_macro(blah)