ANSI C and the C Pre-Processor

Kevin Martin kpmartin at watmath.UUCP
Sat Sep 22 08:29:41 AEST 1984


>> ........................................ However, I have seen plenty of
>> programs which use some of the following constructs:
>> 
>> #define libpath(x)		"/usr/lib/x"
>> #define CTRL(x)			('x'&037)
>> #define PRINT1(format,arg)	printf("arg=%format.\n", arg);
>Such programs are broken and unportable.
>
>> The questions are: Should this change be endorsed? If so, what should be
>> done to bring back the lost functionality? If not, how would you make CPP
>> more regular in its scanning rather than that which is the de-facto standard
>> from Reiser?
>Of course it should be endorsed, since it's not really a change at all.
>				Henry Spencer @ U of Toronto Zoology


For a change, I disagree with Henry. However, there are two questions
here, and I am not sure everyone is making the distinction:
1) Should strings be scanned for token replacement (i.e. look for #define'd
   names and replace them with their expansion)? (I call this "token
   replacement" or "macro substitution")
2) When a #define'd token is being inserted, and its expansion contains
   a string, should that string be scanned for formal parameters to the
   macro? (I call this "parameter substitution")
It is fairly evident that the answer to (1) is NO. Otherwise, no string
would be safe. You couldn't have the name 'putc' in a string, for instance.

I think the answer to (2) is YES. It is often useful to have the formal
parameters substituted into string or character constants, and it is not only
possible but EASY for the programmer to avoid using any formal parameters
which match tokens in any string in the expansion.
e.g. it is easy to avoid #define f(d,x) printf( "%d %d", d, x )

The borderline between (1) and (2) is the size of the area which must be
examined for conflicting identifiers. For (1), you must check every include
file (and the source file up to the occurrence of the string in question).
For (2), you only have the check that the formal parameters don't clash.
And correcting clashes is far easier for (2) than for (1).
                          Kevin Martin, UofW Software Development Group



More information about the Comp.lang.c mailing list