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?