token concatenation macro

T

thomas

----------code-----------------------
#include<iostream>
using namespace std;

#define f(x,y) x##y
#define g(x) #x
#define h(x) g(x)

int main(){
cout<<g(f(1,2))<<endl;
cout<<h(f(1,2))<<endl;
}
---------------code----------------------

the result for g() and h() is different, why?
what's the rule for macro expansion?
 
J

James Kanze

----------code-----------------------
#include<iostream>
using namespace std;

#define f(x,y) x##y
#define g(x) #x
#define h(x) g(x)

int main(){
cout<<g(f(1,2))<<endl;
cout<<h(f(1,2))<<endl;
}

---------------code----------------------

the result for g() and h() is different, why?
what's the rule for macro expansion?

The # and ## operators are evaluated after argument
substitutionm, but before the expansion is rescanned for further
macro replacement. Thus, in the first line, the argument
"f(1,2)" is stringized before the rescan, and of course, once it
has been stringized, it isn't a macro invocation. In the second
line, it gets expanded in h before g(x) is invoked.
 
T

thomas

The # and ## operators are evaluated after argument
substitutionm, but before the expansion is rescanned for further
macro replacement.  Thus, in the first line, the argument
"f(1,2)" is stringized before the rescan, and of course, once it
has been stringized, it isn't a macro invocation.  In the second
line, it gets expanded in h before g(x) is invoked.

what's argument substitution?
is "#define m n" argument substitution?

----------code--------
#include<iostream>
using namespace std;

#define v 1
#define f(x,y) x##y
#define g(x) #x
#define h(x) g(x)

int main(){
cout<<g(f(v,2))<<endl;
cout<<h(f(v,2))<<endl;
}
---------code----------
but the above code prints "f(v,2)" and "v2", while I expect "f(1,2)"
and "12".
 
B

Bart van Ingen Schenau

what's argument substitution?
is "#define m n" argument substitution?

No.
If you have the macro
#define f(x,y) x##y
then x and y are parameters of the macro.
When you invoke the macro as 'f(v,2)', then 'v' and '2' are arguments
to the macro.
In the process of argument substitution, the x and y in the
replacement list of f are substituted with the arguments that were
provided in the invocation.

In detail, macro expansion goes like this:
We start with what was written in the source code: f(v,2)
Macro f is expanded: x##y
The arguments of f are substituted: v##2
Operator # and ## are processed: v2
The result is further scanned for possible replacements. There are no
macros with the name v2, so replacement stops.

Bart v Ingen Schenau
 
J

James Kanze

what's argument substitution?

Argument substitution is when the parameters of a macro are
replaced by the arguments.
is "#define m n" argument substitution?

Where are the arguments? Argument substitution would be when,
given a definition like:

#define f(x,y) 2*(x)+(y)

and an invocation like:
f(a+1, 2*b)
, the preprocessor first generates (internally):
2*(a+1)+(2*b)
After this, it will evaluation the # and ## operators, and then
rescan for more macros. In your example, for example, the first
line of main results in:
g(f(1,2)) // as written
#f(1,2) // after argument substituion, f(1,2)
// is still a "unit" at this point,
// however
"f(1,2)" // After evaluation of # and ##
"f(1,2)" // After rescanning and further macro
// expansion. (Macros in string
// literals are not recognized.)
whereas the second line gives:
h(f(1,2)) // as written
g(f(1,2)) // after argument substituion
g(f(1,2)) // after evaluation of # and ##
g(12) // after expansion of f(1,2) (which
// goes through all of the above steps)
"12" // after expansion of g.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top