16

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.

a3f
  • 8,517
  • 1
  • 41
  • 46
Vitor Baptista
  • 2,016
  • 1
  • 23
  • 28
  • Apparently this (specifically the combination of the `STR` and `XSTR` macros) is called the "double stringize trick". There is a very good explanation in the question [How, exactly, does the double-stringize trick work?](http://stackoverflow.com/questions/2751870/how-exactly-does-the-double-stringize-trick-work) – sleske Jun 05 '14 at 23:18

4 Answers4

21

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.

JSBձոգչ
  • 40,684
  • 18
  • 101
  • 169
5

# 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
  • 9,635
  • 5
  • 62
  • 68
4

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
  • 99,718
  • 31
  • 186
  • 324
  • 5
    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 Aug 20 '10 at 19:25
  • 2
    If you're going to make up words, then "stringify" and "stringise" are just as cromulent as each other. I propose "stringulate". – Mike Seymour Aug 20 '10 at 21:56
  • 1
    @John, I believe you meant: `string s = STR(my quoted string);`, i.e., *without* the quotes (and with the semicolon). – Alok Singhal Aug 20 '10 at 22:47
  • @John Dibling, @Michael Mrozek: At least in C++, that section of the standard is titled `[cpp.stringize]`. – Jerry Coffin Aug 20 '10 at 22:57
  • 1
    @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 Aug 21 '10 at 03:15
  • @John, yeah I don't know what I was thinking. Thanks. – Alok Singhal Aug 21 '10 at 14:01
4

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
  • 476,176
  • 80
  • 629
  • 1,111