C++ #undef的异常行为:宏替换运行结果不符合预期
现象原因
这个问题的核心是C++预处理器不会在宏定义阶段展开替换文本里嵌套的其他宏,所有嵌套宏的展开都发生在宏被实际使用的时刻,代码实际运行逻辑和预期不符的完整流程是:
- 执行
#define MY_CONST 10时,预处理器仅记录一条绑定规则:宏名MY_CONST对应的替换文本是10。 - 执行
#define MY_OTHER_CONST MY_CONST时,预处理器不会当场把替换文本里的MY_CONST替换为10,仅记录宏名MY_OTHER_CONST对应的替换token序列为MY_CONST,不会做任何提前展开或求值。 - 执行
#undef MY_CONST时,预处理器仅删除MY_CONST和10的宏绑定关系,完全不会修改之前存储的MY_OTHER_CONST的替换内容。 - 后续在枚举定义中写
MY_CONST = 100时,MY_CONST已经不属于预处理器识别的宏,这行代码会被当作正常C++语法处理,声明一个值为100、名为MY_CONST的枚举常量。 - 处理到
std::cout << MY_OTHER_CONST;语句时,预处理器才第一次展开MY_OTHER_CONST:先将其替换为存储的tokenMY_CONST,接下来尝试继续展开MY_CONST时,发现该名称已经没有绑定任何宏(早已被#undef取消定义),就会停止宏替换流程,把MY_CONST标识符原封不动留给后续C++编译阶段处理。 - 正式编译阶段,编译器在当前作用域查找
MY_CONST标识符,匹配到的是值为100的枚举常量,因此最终输出结果为100,而非预期的10。
如果要得到预期的输出10,要么不要在#undef MY_CONST之后定义同名的普通标识符,要么通过其他方式在定义MY_OTHER_CONST时就固化MY_CONST的当前值,不要依赖宏的延迟展开特性。
对应测试代码如下:
#include <iostream> #define MY_CONST 10 #define MY_OTHER_CONST MY_CONST #undef MY_CONST int main() { enum my_enum : int { MY_CONST = 100 }; std::cout << MY_OTHER_CONST; return 0; }
内容的提问来源于stack exchange,提问作者user3600124
相关产品推荐
相关产品推荐

