tags:

views:

203

answers:

5

I'm reading the phoneME's source code. It's a FOSS JavaME implementation. It's written in C++, and I stumbled upon this:

// Makes a string of the argument (which is not macro-expanded)
#define STR(a) #a

I know C and C++, but I never read something like this. What does the # in #a do?

Also, in the same file, there's:

// Makes a string of the macro expansion of a
#define XSTR(a) STR(a)

I mean, what's the use of defining a new macro, if all it does is calling an existing macro?

The source code is in https://phoneme.dev.java.net/source/browse/phoneme/releases/phoneme_feature-mr2-rel-b23/cldc/src/vm/share/utilities/GlobalDefinitions.hpp?rev=5525&view=markup. You can find it with a CTRL+F.

+2  A: 

Here's some info on stringification: http://gcc.gnu.org/onlinedocs/cpp/Stringification.html

I think it's explained in some detail on this page: http://www.decompile.com/cpp/faq/file_and_line_error_string.htm

John Boker
+4  A: 

# is the stringizing operator. The preprocessor makes a string out of the parameter.

Say you have:

STR(MyClass);

It would be preprocessed as:

"MyClass";

The level of indirection (using XSTR()) has to do with macro expansion rules.

David
+4  A: 

The #a is referred to as the stringizer operator. It takes the formal parameter, in this case a, and turns it in to a string by enclosing it in double quotes.

So if you have:

string s = STR("my quoted string");
cout << s;

The output would be:

"my quoted string"
John Dibling
Not that it matters, but I think "stringizer" is Microsoft-only; it's normally the "stringify" operator, and the process is called "stringification"
Michael Mrozek
Thx for the correction. :)
John Dibling
If you're going to make up words, then "stringify" and "stringise" are just as cromulent as each other. I propose "stringulate".
Mike Seymour
@John, I believe you meant: `string s = STR(my quoted string);`, i.e., *without* the quotes (and with the semicolon).
Alok
@John Dibling, @Michael Mrozek: At least in C++, that section of the standard is titled `[cpp.stringize]`.
Jerry Coffin
@Alok: No, I meant the quotes. The point is that the stringizer, or whatever you prefer to call it as personally I couldn't care less, will return a quoted string. But you're right about the semicolon. Added.
John Dibling
@John, yeah I don't know what I was thinking. Thanks.
Alok
+10  A: 

In the first definition, #a means to print the macro argument as a string. This will turn, e.g. STR(foo) into "foo", but it won't do macro-expansion on its arguments.

The second definition doesn't add anything to the first, but by passing its argument to another macro, it forces full macro expansion of its argument. So XSTR(expr) creates a string of expr with all macros fully expanded.

JSBangs
+3  A: 

First, you should know that this pair of macros is actually fairly common. The first does exactly what the comment says -- it turns an argument into a string by enclosing it in double quotes.

The second is used to cause macro expansion of the argument. You typically use them together something like this:

#define a value_a

printf("%s", XSTR(a));

The macro expansion will expand a out to string_a, and the stringify will turn that into a string, so the output will be value_a.

Jerry Coffin