I know that:
#define foo 4
#define str(s) #s
with str(foo)
writes out: "foo"
, because stringify is executed first of text expansion, but this:
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
with xstr(foo)
writes out: "4"
.
Why? What are the steps involved in the process?
The relevant steps of macro expansion are (per C 2011 [n1570] 6.10.3.1 and C++ 1998 16.3.1):
#
or ##
.Thus, with xstr(foo)
, we have:
str(s)
, contains no #
or ##
, so nothing happens.foo
is replaced with 4
, so it is as if xstr(4)
had been used.str(s)
, the parameter s
is replaced with 4
, producing str(4)
.str(4)
is rescanned. (The resulting steps produce ”4”
.)Note that the problem with str(foo)
is that step 2, which would replace foo
with 4
, comes after step 1, which changes the argument to a string. In step 1, foo
is still foo
; it has not been replaced with 4
, so the result is ”foo”
.
This is why a helper macro is used. It allows us to get a step 2 performed, then use another macro to perform step 1.