Concatenating tokens that aren't parameters, in ANSI C

Paul Hilfinger hilfingr at tully.Berkeley.EDU.berkeley.edu
Tue Jul 26 18:55:32 AEST 1988


In article <4963 at hoptoad.uucp> gnu at 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 at Berkeley.EDU, hilfingr at ginger.Berkeley.EDU



More information about the Comp.std.c mailing list