首页 > 解决方案 > 为什么要在宏扩展之前进行代币替换?

问题描述

考虑以下代码段:

#include <stdio.h>

#define MY_MACRO(\
   arg) \
   arg

#define MY_MACRO2(t1, t2) t1##t2

#define MY_ a

#define MACRO b

int main() {
    printf("%d\n", MY_MACRO2(MY_,MACRO)(45));
    return 0;
}

结果是编译并显示 45,但是,如果MY_MACRO在替换之前被扩展,则此代码不应编译。我注意到这一点的原因是当我在 C 标准中阅读以下内容时:

6.10.3.1(但也符合 C++ 标准)

在确定了调用类函数宏的参数后,将进行参数替换。替换列表中的参数,除非前面有 # 或 ## 预处理标记或后跟 ## 预处理标记(见下文) ,在其中包含的所有宏都被扩展后被相应的参数替换 。在被替换之前,每个参数的预处理标记都被完全宏替换,就好像它们形成了预处理文件的其余部分一样;没有其他可用的预处理令牌

因此,如果参数中包含的所有宏在替换之前都已扩展,为什么我们不以ab(45)?

标签: c++cc-preprocessor

解决方案


让建筑像X(X())工作一样。请注意,在X()扩展X宏时,宏被禁用以避免无限递归。在扩展宏之前扩展参数让我们在参数中使用 X。的实际应用X(X())

#define TEN(x) x x x x x x x x x x
#define HUNDRED(x) TEN(TEN(x))

推荐阅读