Next: Concatenation, Previous: Macro Arguments, Up: Macros [Contents][Index]
Sometimes you may want to convert a macro argument into a string
constant. Parameters are not replaced inside string constants, but
you can use the #
preprocessing operator instead. When a macro
parameter is used with a leading #
, preprocessing replaces it
with the literal text of the actual argument, converted to a string
constant. Unlike normal parameter replacement, the argument is not
macro-expanded first. This is called stringification.
There is no way to combine an argument with surrounding text and stringify it all together. But you can write a series of string constants and stringified arguments. After preprocessing replaces the stringified arguments with string constants, the consecutive string constants will be concatenated into one long string constant (see String Constants).
Here is an example that uses stringification and concatenation of string constants:
#define WARN_IF(EXP) \ do { if (EXP) \ fprintf (stderr, "Warning: " #EXP "\n"); } \ while (0) WARN_IF (x == 0); → do { if (x == 0) fprintf (stderr, "Warning: " "x == 0" "\n"); } while (0);
The argument for EXP
is substituted once, as is, into the
if
statement, and once, stringified, into the argument to
fprintf
. If x
were a macro, it would be expanded in the
if
statement but not in the string.
The do
and while (0)
are a kludge to make it possible to
write WARN_IF (arg);
. The resemblance of WARN_IF
to a function makes that a natural way to write it.
See Swallowing the Semicolon.
Stringification in C involves more than putting double-quote
characters around the fragment. It also backslash-escapes the quotes
surrounding embedded string constants, and all backslashes within
string and character constants, in order to get a valid C string
constant with the proper contents. Thus, stringifying p = "foo\n";
results in "p = \"foo\\n\";". However, backslashes
that are not inside string or character constants are not duplicated:
‘\n’ by itself stringifies to "\n".
All leading and trailing whitespace in text being stringified is ignored. Any sequence of whitespace in the middle of the text is converted to a single space in the stringified result. Comments are replaced by whitespace long before stringification happens, so they never appear in stringified text.
There is no way to convert a macro argument into a character constant.
To stringify the result of expansion of a macro argument, you have to use two levels of macros, like this:
#define xstr(S) str(S) #define str(s) #s #define foo 4 str (foo) → "foo" xstr (foo) → xstr (4) → str (4) → "4"
s
is stringified when it is used in str
, so it is not
macro-expanded first. But S
is an ordinary argument to
xstr
, so it is completely macro-expanded before xstr
itself is expanded (see Argument Prescan). Therefore, by the time
str
gets to its argument text, that text already been
macro-expanded.
Next: Concatenation, Previous: Macro Arguments, Up: Macros [Contents][Index]