使用预处理器宏组成另一个宏调用

Posted

技术标签:

【中文标题】使用预处理器宏组成另一个宏调用【英文标题】:Using preprocessor macros to compose another macro call 【发布时间】:2016-01-06 15:54:11 【问题描述】:

假设我有一个 C++ 预处理器宏定义如下:

#define X(s) std::cout << #s

如果我直接使用的话:

int main() 
    X( hello );

它按预期工作,并且在控制台上打印“hello”。

如果我定义另一个调用它的宏:

#define Y X( hello )
#define X(s) std::cout << #s

int main() 
    Y;

它仍然有效。

但是,如果我尝试从两个或多个不同的宏组合对 X 的调用,则会收到一大堆错误:

#define A X(
#define B hello
#define C )

#define X(s) std::cout << #s << '\n'


int main()

    A B C;

查看输出:http://cpp.sh/5ws5k

为什么我不能从两个或多个宏扩展组成一个宏调用,预处理器不递归地扩展它们?

【问题讨论】:

您应该阅读描述C++ preprocessor 的文档,可能是C++11 或C99 标准。它不像你在做梦那样工作。 我不知道你想在这里实现什么...... 【参考方案1】:

为什么我不能从两个或多个宏扩展组成一个宏调用,预处理器不递归地扩展它们?

您可以编写宏。预处理器确实递归地扩展宏。

但是,它不会先扩展宏的宽度。它首先扩展它们的深度。

您遇到了问题,因为您希望预处理器首先扩展宏宽度。

您可以在 C++11 标准的16.3.4 重新扫描和进一步替换中阅读有关递归宏扩展的更多信息。

【讨论】:

相关 C++ 标准引用:16.3.4 重新扫描和进一步替换 至于“深度”和“宽度”,预处理器两者都做。将开放括号从A 移动到B,并给定#define I(Q) Q,并使用I(A B C),它是works。

以上是关于使用预处理器宏组成另一个宏调用的主要内容,如果未能解决你的问题,请参考以下文章

C 预处理器宏参数在末尾带有空格以进行连接?

预处理器宏扩展为另一个预处理器指令

预处理器宏更改两个目标

Xcode在哪里保存预处理器宏设置

Doxygen C预处理器宏文档样式

Rust的宏可以像C预处理器宏一样扩展为十六进制数吗?