Go Back   Velocity Reviews > Newsgroups > C++
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

C++ - token concatenation macro

 
Thread Tools Search this Thread
Old 11-02-2009, 06:38 AM   #1
Default token concatenation macro


----------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?


thomas
  Reply With Quote
Old 11-02-2009, 10:37 AM   #2
James Kanze
 
Posts: n/a
Default Re: token concatenation macro
On Nov 2, 6:38 am, thomas <freshtho...@gmail.com> wrote:
> ----------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.

--
James Kanze


James Kanze
  Reply With Quote
Old 11-02-2009, 11:08 AM   #3
thomas
 
Posts: n/a
Default Re: token concatenation macro
On Nov 2, 6:37*pm, James Kanze <james.ka...@gmail.com> wrote:
> On Nov 2, 6:38 am, thomas <freshtho...@gmail.com> wrote:
>
>
>
>
>
> > ----------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.
>
> --
> James Kanze- Hide quoted text -
>
> - Show quoted text -


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".


thomas
  Reply With Quote
Old 11-03-2009, 07:54 AM   #4
Bart van Ingen Schenau
 
Posts: n/a
Default Re: token concatenation macro
On Nov 2, 12:08*pm, thomas <freshtho...@gmail.com> wrote:
> On Nov 2, 6:37*pm, James Kanze <james.ka...@gmail.com> wrote:
>
>
>
> > On Nov 2, 6:38 am, thomas <freshtho...@gmail.com> wrote:

>
> > > ----------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.

>
> > --
> > James Kanze

>
> 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


Bart van Ingen Schenau
  Reply With Quote
Old 11-03-2009, 11:15 AM   #5
James Kanze
 
Posts: n/a
Default Re: token concatenation macro
On Nov 2, 11:08 am, thomas <freshtho...@gmail.com> wrote:
> On Nov 2, 6:37 pm, James Kanze <james.ka...@gmail.com> wrote:
> > On Nov 2, 6:38 am, thomas <freshtho...@gmail.com> wrote:


> > > ----------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.


> 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.

--
James Kanze


James Kanze
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Error: expected constructor, destructor or type conversion before '(' token suse Software 0 03-09-2009 03:25 AM
Security via hardware? Michael Pelletier Computer Security 31 05-20-2005 02:38 AM
Good Freeware Macro Recorder? Slyfoot Computer Support 4 08-22-2004 03:15 PM
Macro To Replace things? John Computer Information 3 01-20-2004 06:18 PM
Adding your own icon to the toolbar to run a macro in excel? John Computer Information 1 12-15-2003 12:36 AM




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46