Preprocessor question

Doug Gwyn gwyn at smoke.BRL.MIL
Sat Jan 21 02:07:09 AEST 1989


>> In article <531 at ole.UUCP> ray at ole.UUCP (Ray Berry) writes:
>> >#define VAL 3
>> >#define STR(x) #x
>> >  puts("val is " STR(VAL));
>In article <9433 at smoke.BRL.MIL>, gwyn at smoke.BRL.MIL (Doug Gwyn ) writes:
>> "Before being substituted, each argument's preprocessing tokens are
>> completely macro replaced as if they formed the rest of the
>> translation unit; no other preprocessing tokens are available."
>> So VAL is first expanded to 3 then the #3 is performed to produce
>> "3".
In article <11125 at ulysses.homer.nj.att.com> gsf at ulysses.homer.nj.att.com (Glenn Fowler[eww]) writes:
>unless things changed from the 86 draft, macro arguments subject to the
># and ## operators are not expanded before the # and ## operations, ...

The problem is that the paragraph constituting Section 3.8.3.1 in the
final Draft has unclear binding of qualifications and things qualified.
With creative interpretation, it can be read either way.  Here it is in
its entirety (sentence numbers in left margin for reference):

[1]	After the arguments for the invocation of a function-like
	macro have been identified, argument substitution takes place.
[2]	A parameter in the replacement list, unless preceded by a # or
	## preprocessing token or followed by a ## preprocessing token
	(see below), is replaced by the corresponding argument after
[3]	all macros contained therein have been expanded.  Before being
	substituted, each argument's preprocessing tokens are completely
	macro replaced as if they formed the rest of the translation
	unit; no other preprocessing tokens are available.

The "(see below)" in sentence [2] refers to the sections that describe
the behavior of the # and ## operators.  Particularly relevant here is

[4]	If, in the replacement list, a parameter is immediately preceded
	by a # preprocessing token, both are replaced by a single
	character string literal preprocessing token that contains the
	spelling of the preprocessing token sequence for the
	corresponding argument.

Now, my reading of Section 3.8.3.1 [1] and [3] is that IN ALL CASES the
argument tokens are macro replaced before substitution, and my reading
of [2] is that the # and ## situations call for actions other than simply
"plugging in" the result of the argument macro expansion.  Sentences [1]
and [3] do NOT indicate "Except as noted in sentence [2], ...".

I can see how you might read sentence [2] as saying that in # and ##
context the arguments are not first macro-expanded, and the use of
xstr(s) in the complex example in Section 3.8.3.5 tends to reinforce
that notion.  Unfortunately there is not an unambiguous example given
for a case like the one under discussion.  I'm sure the Redactor has an
opinion about what was intended here, but then so do the authors of
Turbo C and MicroSoft C, and so far we've seen both interpretations.
If Bob Jervis and Dave Prosser both agree on how this is supposed to be
interpreted, then I'll bow to their opinion; they're pretty much the
X3J11 preprocessing gurus.  (If I've been misinterpreting this, then
I'd also recommend that ANSI C tutorials emphasize this item, because
it sure is easy to read the Standard the other way!)



More information about the Comp.lang.c mailing list