Preprocessor – Understanding the stringizing (#) Operator

This is one of three preprocessor operators. The other two operators are the token pasting operator (##) and the define operator.

The behaviour is the same for both C and C++ compilers.

Purpose

The stringizing operator is used to convert parameters passed to a macro into strings.

Format

# token_to_turn_into_a_string

Use

The stringizing (#) operator may only be used with #define preprocessor directives taking a parameter.

The parameter token immediately to the right of the stringizing operator (ignoring any white space) is transformed by the preprocessor into a string.

For example:

#define make_string(x) #x

will convert whatever is passed as parameter x into a string.

Leading and trailing white space are deleted.

Any white space between the parameter’s tokens are collapsed into a single white space character between tokens.

Any conversions necessary to make character literals in the parameter’s tokens valid in a string are automatically made. This means that characters like: \ and " are automatically converted to \\ and \" respectively.

If the token is a macro, the macro is not expanded – the macro name is converted into a string. As a consequence, some characters cannot be stringized – notably, the comma (,) because it is used to delimit parameters and the right parenthesis ()) because it marks the end of the parameter list.

Examples

Given the following macros:

#define make_string(x) #x

#define COMMA ,

the following uses:

make_string(twas brillig);
make_string( twas brillig );
make_string("twas" "brillig");
make_string(twas COMMA brillig);

get expanded into:

// no surprise here
"twas brillig"
// leading and trailing spaces were trimmed,
// space between words was compressed to a single space character
"twas brillig"
// the quotes were automatically converted
"\"twas\" \"brillig\""
// the macro COMMA was not expanded
"twas COMMA brillig"

In C99 and the upcoming C++0x languages, you can use a variadic macro to pass commas to the stringizing operator.

#define make_string(...) # __VA_ARGS__

Since __VA_ARGS__ does not process the comma separator, you can pass it to the stringizing operator. However, you still cannot pass the right parenthesis.

Stringizing a Single Character

Sometimes you want to create a character literal. Unfortunately, the language does not specify a charizing operator (although, the Microsoft compiler does provide the non-standard operator #@ for charizing a single character).

However, you can simulate a charizing operator as follows:

#define CHARIZE(x) #x[0]

What this does is stringize whatever is passed as parameter x and then addresses the first character – effectively acting as though the parameter had been charized. This works in most places a character literal is expected, but not all.