奇怪的c ++预处理器行为

时间:2014-06-25 15:23:56

标签: c++ macros c-preprocessor stringification

请考虑以下代码:

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

M(VAR);
M2(VAR);

使用以下命令行: cpp test.cpp -DVAR = xxx

我希望预处理器改变M(x)和M2(x) 进入“xxx”。

但只有M2被替换。那是为什么?

1 个答案:

答案 0 :(得分:3)

当我尝试这个时,我得到:

"VAR";
"abc";

(你应该在你的问题中包含哪些内容!)

As this page explains.

  

如果要对宏参数的扩展结果进行字符串化,   你必须使用两个级别的宏。

 #define xstr(s) str(s)
 #define str(s) #s
 #define foo 4
 str (foo)
      ==> "foo"
 xstr (foo)
      ==> xstr (4)
      ==> str (4)
      ==> "4"
  

在str中使用时会被字符串化,因此它不是宏扩展的   第一。但是s是xstr的普通参数,所以它完全是   在xstr本身扩展之前进行宏扩展。因此,到时候   str得到它的论点,它已经被宏观扩展。

这是因为预处理程序的预扫描宏参数的规则被解释为here

该页面的重点是:

  

调用其他字符串化或连接的宏。

     

如果参数被字符串化或连接,则预扫描不会   发生。如果要扩展宏,则进行字符串化或连接   它的扩展,你可以通过使一个宏调用另一个宏来做到这一点   执行字符串化或连接的宏。例如,如果   你有

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

AFTERX(BUFSIZE)扩展为X_BUFSIZE,XAFTERX(BUFSIZE)扩展为X_1024。 (不是   X_TABLESIZE。预扫描总是完全扩展。)