Help me to understand this macro

A

Amp Sand

I'm studying how C preprocessor works and i've found this example on
wikipedia

#define FOO bar
#define _QUOTEME(x) #x
#define QUOTEME(x) _QUOTEME(x)

in this way # operator can be used to quote the value of a macro and
not its parameter. I don't understand how macro expansion works....fo
example:

1. printf("FOO=%s\n", QUOTEME(FOO));
2. printf("FOO=%s\n", _QUOTEME(FOO)); (underscore in _QUOTEME(FOO) is
due to convention or to something else?)
3. printf("FOO=%s\n", _QUOTEME(bar));
4. printf("FOO=%s\n",bar);

In this way the correct value is obtained, but i don't unterstand why
step 3 is done before step 4
Any help?
 
A

Amp Sand

 _QUOTEME(x) became "x"
 _QUOTEME(a) became "a"
 _QUOTEME(1) became "1"

Ok, but this is not my question...if i have

#define FOO bar
#define QUOTEME(x) #x
.....
printf("FOO=%s\n", QUOTEME(FOO));

with macro expansion i obtain

printf("FOO=%s\n", QUOTEME(FOO)); ==> FOO=FOO

so macro expansion for FOO (to bar) is not present: # is used to
transform to string a macro argument (in this case FOO). If i consider
this case:

#define FOO bar
#define _QUOTEME(x) #x
#define QUOTEME(x) _QUOTEME(x)

printf("FOO=%s\n", QUOTEME(FOO));

with macro expansion i obtain

printf("FOO=%s\n", _QUOTEME(bar));

and not

printf("FOO=%s\n", _QUOTEME(FOO));

so FOO expansion is present...which rules are present in this case?
why i not obtain something like printf("FOO=%s\n", _QUOTEME(FOO)) ?

Thanks
 
T

Thad Smith

Amp said:
I'm studying how C preprocessor works and i've found this example on
wikipedia

#define FOO bar
#define _QUOTEME(x) #x
#define QUOTEME(x) _QUOTEME(x)

in this way # operator can be used to quote the value of a macro and
not its parameter. I don't understand how macro expansion works....fo
example:

1. printf("FOO=%s\n", QUOTEME(FOO));
2. printf("FOO=%s\n", _QUOTEME(FOO)); (underscore in _QUOTEME(FOO) is
due to convention or to something else?)

Underscore is a convention, although a poor one, since it intrudes on
the implementer's name space. Alternative names, not intruding, name
would be QUOTEME_ or QUOTEME2. The essence is: QUOTEME is the macro to
be used, while _QUOTEME is intended as a helper macro for QUOTEME.
3. printf("FOO=%s\n", _QUOTEME(bar));
4. printf("FOO=%s\n",bar);

If the body of a function-like macro contains the # operator, the # and
following parameter are replaced by a string constant which expands to
the image of the parameter. Thus _QUOTEME(FOO) is replaced by "FOO".

If the body of a function-like macro contains a parameter without
preceding #, the parameter is expanded by macro substitution before
rescanning the body of the macro for more substitutions. Thus
QUOTEME(FOO) is first expanded to _QUOTEME(bar), then "bar" on rescanning.
In this way the correct value is obtained, but i don't unterstand why
step 3 is done before step 4

What are you calling step 3 and step 4? Your numbered statements don't
indicate "steps" to me.
 
B

Ben Bacarisse

Amp Sand said:
...if i have

#define FOO bar
#define QUOTEME(x) #x
....
printf("FOO=%s\n", QUOTEME(FOO));

with macro expansion i obtain

printf("FOO=%s\n", QUOTEME(FOO)); ==> FOO=FOO

so macro expansion for FOO (to bar) is not present: # is used to
transform to string a macro argument (in this case FOO).

Thad has explained this but maybe it will help if I do so interleaved
with this reply. In the case above, with no "helper" macro, the
scanned sees 'QUOTE(' and knows that is must collect a comma separated
list of token lists. The 'x' in the body of QUOTEME is associated
with the token 'FOO' and the body replacement of #x becomes "FOO".

This is a special rule. Both # and ## prevent any further macros
expansion:

6.10.3.1 Argument substitution

1 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. [...]

I.e. the replacement text for macro arguments are explicitly /not/
expanded if they are preceded by # or ##.

Note, also, that no macros are expanded as the arguments are
collected. If any subsequent expansion does occur, it is done as the
replacement text is being substituted into the macro body.
If i consider
this case:

#define FOO bar
#define _QUOTEME(x) #x
#define QUOTEME(x) _QUOTEME(x)

printf("FOO=%s\n", QUOTEME(FOO));

with macro expansion i obtain

printf("FOO=%s\n", _QUOTEME(bar));

and not

printf("FOO=%s\n", _QUOTEME(FOO));

so FOO expansion is present...which rules are present in this case?
why i not obtain something like printf("FOO=%s\n", _QUOTEME(FOO)) ?

Here 'QUOTEME(FOO)' expands to '_QUOTEME(bar)' because, after x is
associated with 'FOO', x is "replaced by the corresponding argument
after all macros contained therein have been expanded". I.e. x is
replaced with 'bar' because FOO can be expanded.

The result of the expansion is then re-scanned for any further
replacement so the '_QUOTEME(bar)' invocation is then replaced as
you'd expect (x is associated with 'bar' and #x becomes "bar").
 
K

Keith Thompson

Amp Sand said:
I'm studying how C preprocessor works and i've found this example on
wikipedia

#define FOO bar
#define _QUOTEME(x) #x
#define QUOTEME(x) _QUOTEME(x)
[...]

This is in <http://en.wikipedia.org/wiki/C_preprocessor>.

As Thad Smith mentioned, "_QUOTEME" is a poor name, especially in
demonstration code, since it intrudes in the implementation's
namespace. Since it's on Wikipedia, would someone like to fix it?
 
B

Ben Bacarisse

Keith Thompson said:
Amp Sand said:
I'm studying how C preprocessor works and i've found this example on
wikipedia

#define FOO bar
#define _QUOTEME(x) #x
#define QUOTEME(x) _QUOTEME(x)
[...]

This is in <http://en.wikipedia.org/wiki/C_preprocessor>.

As Thad Smith mentioned, "_QUOTEME" is a poor name, especially in
demonstration code, since it intrudes in the implementation's
namespace. Since it's on Wikipedia, would someone like to fix it?

Done.
 

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

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top