在C语言中如何备份#define宏的取值?
怎么保存
_XOPEN_SOURCE的原始宏值 你的备份方法不管用,核心问题出在预处理器的宏替换逻辑:当你写#define _XOPEN_SOURCE_BACK _XOPEN_SOURCE时,它并没有把_XOPEN_SOURCE当时的600直接存进_XOPEN_SOURCE_BACK,只是给_XOPEN_SOURCE_BACK加了个「展开时用当前_XOPEN_SOURCE的值」的关联。后面_XOPEN_SOURCE被修改或者取消定义后,_XOPEN_SOURCE_BACK自然就跟着变了。
靠谱的解决办法:用两层宏固化原始值
通过两层宏嵌套,能强制预处理器在定义备份宏的时候,就把_XOPEN_SOURCE的当前值直接写死进去,不再和原宏关联。
代码示例
// 先捕获_XOPEN_SOURCE的原始值 #ifdef _XOPEN_SOURCE #define _CAPTURE_VAL(val) val #define _XOPEN_SOURCE_BACK _CAPTURE_VAL(_XOPEN_SOURCE) #undef _XOPEN_SOURCE #endif // 引入会修改宏的头文件 #include "xxx.h" // 恢复原始的_XOPEN_SOURCE值 #ifdef _XOPEN_SOURCE_BACK #undef _XOPEN_SOURCE #define _XOPEN_SOURCE _XOPEN_SOURCE_BACK #endif
为啥这招管用
_CAPTURE_VAL(val)是个中间宏,作用是触发预处理器立刻展开传入的参数。- 定义
_XOPEN_SOURCE_BACK时,_CAPTURE_VAL(_XOPEN_SOURCE)会先把_XOPEN_SOURCE展开成600,再赋值给_XOPEN_SOURCE_BACK。此时_XOPEN_SOURCE_BACK的实际定义就是#define _XOPEN_SOURCE_BACK 600,和原宏彻底解绑。 - 后续哪怕
xxx.h把_XOPEN_SOURCE改成700,_XOPEN_SOURCE_BACK的值还是600,完全不受影响。
备选方案:字符串化+反字符串化(应付复杂场景)
如果遇到带空格或者特殊字符的宏值,还可以用字符串化再转回来的方式:
#ifdef _XOPEN_SOURCE #define _TO_STR(s) #s #define _STR(s) _TO_STR(s) #define _XOPEN_SOURCE_BACK _STR(_XOPEN_SOURCE) #undef _XOPEN_SOURCE #endif #include "xxx.h" #ifdef _XOPEN_SOURCE_BACK #undef _XOPEN_SOURCE #define _XOPEN_SOURCE _XOPEN_SOURCE_BACK #endif
这里_STR(_XOPEN_SOURCE)会先把_XOPEN_SOURCE展开成600,再转成字符串"600",预处理器会自动把这个字符串常量转换成数值,恢复的时候照样能正常使用。
内容的提问来源于stack exchange,提问作者킵고잉
相关产品推荐
相关产品推荐

