能否通过C++宏实现FOO与BAR的非循环双向替换?
实现FOO与BAR的双向宏替换
原代码
#include <cstdio> #define FOO BAR #define BAR FOO #define QUOTE(X) #X #define EXPAND(X) QUOTE(X) int main() { printf("%s expands to %s\n", QUOTE(FOO), EXPAND(FOO)); printf("%s expands to %s\n", QUOTE(BAR), EXPAND(BAR)); }
原程序输出
FOO expands to FOO BAR expands to BAR
问题根源
FOO展开为BAR后,预处理器处理BAR的替换时,会发现BAR指向的FOO是刚才正在处理的宏标识符,为了防止无限递归,预处理器不会再次展开FOO,最终结果停在FOO;BAR的展开逻辑同理,所以替换后的结果和原标识符一致。
需求
仅修改#define FOO BAR和#define BAR FOO这两行宏定义,实现FOO与BAR的双向替换,让程序输出:
FOO expands to BAR BAR expands to FOO
解决方案
引入中间过渡宏打破循环限制,修改后的宏定义如下:
#define FOO _BAR #define BAR _FOO #define _BAR BAR #define _FOO FOO
原理
预处理器的递归防护规则是:在处理某宏的替换流程中,不会再次展开同一个宏标识符。我们通过过渡宏_BAR和_FOO把替换路径拆成两层:
- 处理
FOO时,先替换为_BAR,_BAR是未参与初始FOO替换流程的新宏,因此可以正常展开为BAR,此时BAR不会被递归回FOO(当前处理的是_BAR的展开,BAR的替换不会触发已处理过的FOO) - 处理
BAR时,先替换为_FOO,再展开为FOO,最终实现双向替换的预期效果
完整修改代码
#include <cstdio> #define FOO _BAR #define BAR _FOO #define _BAR BAR #define _FOO FOO #define QUOTE(X) #X #define EXPAND(X) QUOTE(X) int main() { printf("%s expands to %s\n", QUOTE(FOO), EXPAND(FOO)); printf("%s expands to %s\n", QUOTE(BAR), EXPAND(BAR)); }
运行输出
FOO expands to BAR BAR expands to FOO
内容的提问来源于stack exchange,提问作者David Brink
相关产品推荐
相关产品推荐

