[comp.std.c] Concatenating tokens that aren't parameters, in ANSI C

gnu@hoptoad.uucp (John Gilmore) (07/26/88)

I'm still trying to get Unix to compile and run under an ANSI C compiler
(gcc).  The latest wierd problem comes from the Fortran I/O library, where
they define the number of significant digits in a float and then want
to define a constant containing 1e(that number).  Under pcc, they used:

#define LFD 6
#define LHIGH 1.0e+LFD

which expanded to

1.0e+6

which worked just fine.  This no longer works, since the preprocessor
works on "pp-tokens" one of which is a "pp-number" which includes all
of "1.0e+LFD" (once you've seen a digit, it includes letters and digits
and "e"s followed by signs until kingdom come).  It never sees "LFD" as
a separate token like the old one did.  I have tried various kludges to
make this work; the obvious:

#define LHIGH 1.0e+ ## LFD

fails because ## does not fully expand its arguments before concatenating
them; it only expands them if they are parameters to the macro (boo!).
I tried various more complex alternatives and NEVER got any of them to
work.  Some of this may be due to gcc-1.24 bugs; I expect that:

#define cat_a(a,b) a ## b
#define cat_b(a,b) a ## b
#define LHIGH cat_a(1.0e+,cat_b(LFD,))

should work, but it produces:

1.0e+cat_b(6 ,)  

a wierd result, probably due to misimplementation of the overly complex
ANSI C anti-self-calling rules.

If C had exponentiation, I could define LHIGH (10.**(LFD-1)) and hope
for constant folding, but there's no **.  Does anyone have any suggestions?
-- 
John Gilmore    {sun,pacbell,uunet,pyramid,amdahl}!hoptoad!gnu    gnu@toad.com
      "And if there's danger don't you try to overlook it,
       Because you knew the job was dangerous when you took it"

hilfingr@tully.Berkeley.EDU.berkeley.edu (Paul Hilfinger) (07/26/88)

In article <4963@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>I'm still trying to get Unix to compile and run under an ANSI C compiler
>(gcc).  The latest wierd problem comes from the Fortran I/O library, where
>they define the number of significant digits in a float and then want
>to define a constant containing 1e(that number).  Under pcc, they used:
>
>#define LFD 6
>#define LHIGH 1.0e+LFD
>
>which expanded to
>
>1.0e+6
>
>which worked just fine.  This no longer works,....

The following works (I have tried it under gcc):

    #define cat_a(a,b) a ## b
    #define cat_b(a,b) cat_a(a,b)
    #define LHIGH cat_b(1.0e+,LFD)

This is because, as specified in the ANSI Standard, the LFD argument is
expanded before substitution into the definition of cat_b, so that a 
macro invocation of LHIGH becomes
    cat_a(1.0e+,6)
 
>Some of this [weirdness] may be due to gcc-1.24 bugs; I expect that:
>
>#define cat_a(a,b) a ## b
>#define cat_b(a,b) a ## b
>#define LHIGH cat_a(1.0e+,cat_b(LFD,))
>
>should work, but it produces:
>
>1.0e+cat_b(6 ,)  
>
>a wierd result, probably due to misimplementation of the overly complex
>ANSI C anti-self-calling rules.

Not so weird.  Given that the original version didn't work in gcc because
LFD immediately after the 1.0e+ was not recognized as a macro name, it is
consistent that cat_b should not be recognized as a macro name 
right after 1.0e+.

I confess, however, that I am a relative newcomer to the ANSI C standard,
and am not sure whether gcc's behavior is correct.

Paul Hilfinger
University of California at Berkeley
Hilfinger@Berkeley.EDU, hilfingr@ginger.Berkeley.EDU

mmengel@cuuxb.ATT.COM (~XT4103000~Marc Mengel~C25~G25~6184~) (07/27/88)

In article <4963@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
[old code breaks under ANSI cpp follows]
>#define LFD 6
>#define LHIGH 1.0e+LFD
>which expanded to
>1.0e+6
 [tried]
>#define LHIGH 1.0e+ ## LFD
 [and also]
>#define cat_a(a,b) a ## b
>#define cat_b(a,b) a ## b
>#define LHIGH cat_a(1.0e+,cat_b(LFD,))
>
>should work, but it produces:
>
>1.0e+cat_b(6 ,)  

Hmmm. seeems like maybe
#define LFD	6
#define BASE	1.0e
#define LHIGH	LFD+BASE

might just work, I don't have a gcc cpp handy to test it though. (It
works under SysV cc.

>John Gilmore    {sun,pacbell,uunet,pyramid,amdahl}!hoptoad!gnu    gnu@toad.com


-- 
 Marc Mengel			       
				
 attmail!mmengel	
 {lll-crg|mtune|ihnp4}!cuuxb!mmengel