Path: utzoo!attcan!uunet!lll-winken!ncis.llnl.gov!helios.ee.lbl.gov!nosc!ucsd!rutgers!cmcl2!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn ) Newsgroups: comp.lang.c Subject: Re: Preprocessor question Message-ID: <9453@smoke.BRL.MIL> Date: 20 Jan 89 16:07:09 GMT References: <531@ole.UUCP> <9433@smoke.BRL.MIL> <11125@ulysses.homer.nj.att.com> Reply-To: gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 56 >> In article <531@ole.UUCP> ray@ole.UUCP (Ray Berry) writes: >> >#define VAL 3 >> >#define STR(x) #x >> > puts("val is " STR(VAL)); >In article <9433@smoke.BRL.MIL>, gwyn@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@ulysses.homer.nj.att.com> gsf@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!)