[comp.lang.c] Expansion of macro arguments in ANSI cpp.

grahamd@otc.otca.oz.au (Graham Dumpleton) (04/23/91)

I checked the FAQ list but couldn't find this mentioned so:

What is an ANSI conforming C preprocessor mean't to do in the following
situation.

#define preone onepre
#define one two
#define addpre(arg) pre##arg

addpre(one)


The preprocessor on a RS6000 running AIX when run with the argument
'-qlanglvl=ansi' to invoke ANSI compatability produces

onepre

In other words it performs the join and then checks to see if the result
is a macro and if so expands it.

The pre-processor which we use though, which is based on the Decus cpp supplied
on the X tape produces the following

pretwo

In other words it has the effect of expanding the argument if it is a macro
first and then performing the join.

I tend to think that the Decus cpp is wrong but can someone please confirm this.

--
Graham Dumpleton (grahamd@otc.otca.oz.au)

steve@taumet.com (Stephen Clamage) (04/23/91)

grahamd@otc.otca.oz.au (Graham Dumpleton) writes:

>	#define preone onepre
>	#define one two
>	#define addpre(arg) pre##arg
>	addpre(one)
>The preprocessor on a RS6000 running AIX when run with the argument
>'-qlanglvl=ansi' to invoke ANSI compatability produces
>	onepre

>The pre-processor which we use though, which is based on the Decus cpp supplied
>on the X tape produces the following
>	pretwo

>I tend to think that the Decus cpp is wrong but can someone please confirm this.

Decus is wrong.  Section 3.8.3.1 of the Standard decribes how macro
argument substitution operates.  After identifying the arguments,
those which are neither preceeded by # or ##, nor followed by ##, are
fully macro-replaced; the others are left alone.  In your example, the
'arg' macro is preceeded by ##, so its actual parameter is not expanded.
After concatenation, we have 'preone', which is then rescanned to
produce 'onepre'.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

sarima@tdatirv.UUCP (Stanley Friesen) (04/24/91)

In article <2610@otc.otca.oz> grahamd@otc.otca.oz.au (Graham Dumpleton) writes:
<What is an ANSI conforming C preprocessor mean't to do in the following
<situation.
<
<#define preone onepre
<#define one two
<#define addpre(arg) pre##arg
<
<addpre(one)

I believe that the ANSI standard requires that macro arguments be expanded
before substitution into the macro body, and therefor before expansion of
the macro itself into the source.

Thus the answer is:

pretwo
 
<The preprocessor on a RS6000 running AIX ...
 
<onepre
 
I believe that this is *wrong* per the standard.
(I do not actually have a copy present with me, so I could be wrong).
-- 
---------------
uunet!tdatirv!sarima				(Stanley Friesen)

sparks@suntan.viewlogic.com (Alan Sparks) (05/04/91)

In article <208@tdatirv.UUCP>, sarima@tdatirv.UUCP (Stanley Friesen) writes:
|> In article <2610@otc.otca.oz> grahamd@otc.otca.oz.au (Graham Dumpleton) writes:
|> <What is an ANSI conforming C preprocessor mean't to do in the following
|> <situation.
|> <
|> <#define preone onepre
|> <#define one two
|> <#define addpre(arg) pre##arg
|> <
|> <addpre(one)
|> 
|> I believe that the ANSI standard requires that macro arguments be expanded
|> before substitution into the macro body, and therefor before expansion of
|> the macro itself into the source.
|> 
|> Thus the answer is:
|> 
|> pretwo
|>  
|> <The preprocessor on a RS6000 running AIX ...
|>  
|> <onepre
|>  
|> I believe that this is *wrong* per the standard.
|> (I do not actually have a copy present with me, so I could be wrong).
|> -- 
|> ---------------
|> uunet!tdatirv!sarima				(Stanley Friesen)

Paragraphs in the Standard suggest that AIX is correct (section A12.3):

"... Unless the parameter in the replacement sequence is preceded by #,
or preceded or followed by ##, the argument tokens are examined for
macro calls and expanded as necessary, just before insertion."

".. Second, if the definition token sequence ... contains a ## operator,
then just after replacement of the parameters, each ## is deleted, together with any whitespace on either side, so as to concatenate the
adjacent tokens and form a new token."

"In both kinds of macro, the replacement token sequence is repeatedly
rescanned for more defined identifiers."

So, this suggests that 

	addpre(one)

turns into

	pre ## one

and (after concatenation),

	preone

and finally, after rescan, 

	onepre

-Alan
-- 

Alan Sparks      voice: (508) 480-0881  Internet: sparks@viewlogic.com
VIEWlogic Systems Inc., 293 Boston Post Rd. W., Marlboro MA 01752
Disclaimer: VIEWlogic didn't say this; I might have.  Who's asking?