Shao Miller
7/7/2011 10:21:00 PM
On 7/6/2011 17:27, Paul N wrote:
> On Jul 6, 12:06 pm, Michael DOUBEZ<michael.dou...@free.fr> wrote:
>>
>> #define PCAT( x, y) x##y
>> #define SET_VAR_NNN(n) int PCAT(var,n)
>> #define SET_VAR SET_VAR_NNN(__LINE__)
>
> When I saw this question, I suspected the answer would be along those
> lines, but I'm afraid I still can't see why the second form works and
> the first form doesn't. Could someone explain to me?
>
> In my naive way, I would expect the preprocessor to either substitute
> the arguments and then the functions, or vice versa. So I would have
> expected either the first version to work as follows:
>
> SET_VAR; becomes
> SET_VAR_NNN(__LINE__); becomes
> SET_VAR_NNN(6); becomes
> var##6; becomes
> var6;
>
> (ie first version works)
>
> or for the second version to go:
>
> SET_VAR; becomes
> SET_VAR_NNN(__LINE__); becomes
> int PCAT(var,__LINE__); becomes
> int var##__LINE__; becomes
> int var__LINE__;
>
> (ie second version doesn't work).
>
> I can't see what magic it must do to allow the frst form not to work
> but the second to work. I've had a quick look at both the Standard and
> the FAQ, but the penny hasn't dropped.
The relevant portions of the Standard might be 6.10.3.3p2, 6.10.3.3p3,
6.10.3.4, if I understand them correctly.
SET_VAR
/* Replacement list */
SET_VAR_NNN(__LINE__)
/* Rescan finds 'SET_VAR_NNN()' and substitutes replacement list */
int PCAT(var,n)
/* Argument substitution "all macros contained therein" */
__LINE__
6
/* Argument substitution "after" */
int PCAT(var,6)
/* Rescan finds 'PCAT()' and substitutes replacement list*/
x##y
/* "...preceded or followed by a ##..." */
var6
/* Rescan finds nothing */
Contrast with the original:
SET_VAR
/* Replacement list */
SET_VAR_NNN(__LINE__)
/* Rescan finds 'SET_VAR_NNN()' and substitutes replacement list */
int var##n
/* "...preceded or followed by a ##..." */
int var__LINE__
/* Rescan finds nothing */
I hope this helps (and hope it doesn't contain an error)! :)