Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: Sort char array
Date: Sat, 19 Oct 2019 06:00:56 -0700
Organization: A noiseless patient Spider
Lines: 102
Message-ID: <86v9skhotz.fsf@linuxsc.com>
References: <87tv8ggaxh.fsf@bsb.me.uk> <87mue8fx7b.fsf@bsb.me.uk> <1QInF.797536$aq7.506537@fx09.am4> <875zkwf27e.fsf@bsb.me.uk> <87a7a66eyk.fsf@bsb.me.uk> <6%ioF.849405$893.123190@fx02.am4> <20191014013916.333bfd71e8363156058a1b2e@gmail.com> <86imor73wp.fsf@linuxsc.com> <20191015002630.213bbd842f2f5aa17c73015d@gmail.com> <8636fs6adz.fsf@linuxsc.com> <20191019003905.826b918468a4ab42279e0ea4@gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="3a1975e3f550932398983d5ed513e7ac"; logging-data="21441"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+WCrNlakG1I/EUV7nfQRpCsDDm9ltfZCw="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:9lHADFC3YMR0MYwFVRVCyytwLsY= sha1:MTYqAhBr02wbeKUu5m68/s9e2m8=
Xref: csiph.com comp.lang.c:147073
Anton Shepelev writes:
> [..getting a macro argument to expand before token pasting..]
>
> The solution I wrote applies to a single function:
>
> #define PREF MyPrefix_ /* a global setting */
>
> #define FID( F ) FID1(PREF, F)
> #define FID1(P,F) FID2( P, F)
> #define FID2(P,F) P ## F
>
>> [I wrote:]
>> Try tracing through what happens during macro processing, using
>> the descriptions in the C standard for how expansion works, and
>> see if it makes sense what is going on and why.
>
> After reading about that in the standard, I still do not
> understand why my solution requires both FID1 and FID2 to
> expand PREF. As far as I have understood the starndard,
> PREF should be expanded during the rescan stage of FID
> expansion, but it is not. Why?
We start with a call to the FID() macro:
^ FID( some_name ) ...
The ^ indicates the scan arrow, the ... indicates the rest of the
file. Assuming the argument 'some_name' is already fully
expanded, the first level of expansion gives this:
^ FID1( PREF, some_name ) ...
(I have added some extra white space, but that doesn't change
anything important.)
In expanding this macro call, the argument PREF is expanded
before being substituted for P in the definition 'FID2( P, F )',
so we get
^ FID2( MyPrefix_, some_name ) ...
which upon one expansion gives
^ MyPrefix_some_name ...
at which point, assuming 'MyPrefix_some_name' is not defined as a
macro, leads to
MyPrefix_some_name ^ ...
which is what we want.
Now suppose the FID() macro had used FID2() rather than FID1().
Then the first level of expanding FID( some_name ) gives this:
^ FID2( PREF, some_name ) ...
At this point we need to replace a call to FID2(), which is
defined as
#define FID2(P,F) P ## F
The first argument, PREF, is substituted for P in the definition.
But how is it substituted? The specification for that is given in
section 6.10.3.1. Paragraph 1 of that section starts
After the arguments for the invocation of a function-like
macro have been identified, argument substitution takes place.
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
all macros contained therein have been expanded.
Note the key second sentence: a macro parameter is replaced by
the expanded argument "unless preceded by a # or ## preprocessing
token or followed by a ## preprocessing token". In the definition
of FID2, the (single occurrence of the) parameter P is followed by
a ## operator. Therefore the first argument to the call of FID2()
is _not_ expanded but substituted as is. Therefore the call
to FID2() gives
^ PREFsome_name ...
but PREF has now been pasted onto some_name, so it doesn't expand
as the token PREF would.
We can test this theory by defining PREFsome_name:
#define PREFsome_name HOLY_SMOKES
#define PREF MYPrefix_
#define FID( F ) FID2(PREF, F)
#define FID2(P,F) P ## F
FID( some_name )
Running this example through gcc -E does indeed expand the call of
PREFsome_name to its definition, HOLY_SMOKES. Give it a try.
Does this explanation help you see what is going on and why?