1

Consider the following code:

#define M(x) #x
#define M2(x) M(x)

M(VAR);
M2(VAR);

With the following command line: cpp test.cpp -DVAR=xxx

I would expect from the pre-processor to change both M(x) and M2(x) into "xxx".

But only M2 is replaced. Why is that?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
buc030
  • 425
  • 3
  • 14

1 Answers1

3

When I try this I get:

"VAR";
"abc";

(WHICH YOU SHOULD HAVE INCLUDED IN YOUR QUESTION!)

As this page explains.

If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros.

 #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. Therefore, by the time str gets to its argument, it has already been macro-expanded.

This happens because of the preprocessor's rules for prescanning macro arguments which are explained here:

The important point from that page is:

Macros that call other macros that stringify or concatenate.

If an argument is stringified or concatenated, the prescan does not occur. If you want to expand a macro, then stringify or concatenate its expansion, you can do that by causing one macro to call another macro that does the stringification or concatenation. For instance, if you have

      #define AFTERX(x) X_ ## x
      #define XAFTERX(x) AFTERX(x)
      #define TABLESIZE 1024
      #define BUFSIZE TABLESIZE 

AFTERX(BUFSIZE) expands to X_BUFSIZE, and XAFTERX(BUFSIZE) expands to X_1024. (Not to X_TABLESIZE. Prescan always does a complete expansion.)

Dale Wilson
  • 9,166
  • 3
  • 34
  • 52
  • Obviously, the question is why is that? – buc030 Jun 25 '14 at 15:44
  • The short answer is "because that is the way the preprocessor has always worked." For the long answer read the page I linked to (click on "As this page explains". Don't forget to follow the "Argument Prescan link.) [I'll edit my answer to include info from that page, too] – Dale Wilson Jun 25 '14 at 15:48