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

Weird c++ pre processor behaviour

本文关键字:处理器 预处理 c++      更新时间:2023-10-16

考虑以下代码:

#define M(x) #x
#define M2(x) M(x)
M(VAR);
M2(VAR);

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

我希望预处理器同时改变M(x)和M2(x)进入"xxx"。

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

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

"VAR";
"abc";

(你应该把它包括在你的问题里!)

本页解释

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

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

s在str中使用时会被字符串化,因此不会进行宏展开第一。但是s是xstr的一个普通参数,所以它完全是在XSTR本身展开之前进行宏展开。因此,随着时间的推移当STR到达它的实参时,它已经被宏展开了。

这是因为预处理器对预扫描宏参数的规则,如下所示:

那一页的重点是:

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

如果参数被字符串化或连接,则预扫描不会发生。如果要展开宏,请进行字符串化或连接它的展开,可以通过让一个宏调用另一个宏来实现执行字符串化或连接的宏。例如,如果你有

      #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。预扫描总是执行完全展开。)