【C/C++】防止不必要的局部宏替换
避免和防止宏定义在不必要的位置进行替换。
1. - 问题分析
宏定义为纯文本替换,防止宏替换只能使用 #undef , 并且为了避免影响到其他的代码又需要 重新定义出来。
#if defined(_WIN32) || defined(WIN64) || defined(_MSC_VER)
#define SPRINTF sprintf_s
#elif defined(__linux__) || defined(__GNUC__)
#define SPRINTF sprintf
#endif
#ifdef SPRINTF
#undef SPRINTF
#endif
// redefine
// ...
但这种方法非常麻烦。
2. - 具体背景
由于项目跨平台为了更好的适配代码,在某些平台下使用了宏。
#define sprintf _sprintf
为了较方便的操作 json ,项目使用了 nlohmann/json ,
但 json.hpp 中,这句话就会与跨平台的文件产生问题
(std::snprintf)(cs.data(), cs.size(), "<U+%.4>", static_cast<unsigned char>(c));
编译时报错
C2039 “_snprintf”: 不是“std”的成员 (编译源文件:D:\xxxx\...\xxx.cpp)
3. - 解决方案
需要在会替换的地方添加上 #pragma push_macro 和 #pragma pop_macro 预编译指令,示例如下:
#define X 1
#pragma push_macro("X")
#undef X
#define X -1
#pragma pop_macro("X")
int x [X];
#pragma push_macro 用于保存 (save) 宏定义
#pragma pop_macro 用于还原 (restore) 宏定义
替换:
#pragma push_macro("snprintf")
#undef snprintf
(std::snprintf)(cs.data(), cs.size(), "<U+%.4>", static_cast<unsigned char>(c));
#pragma pop_macro("snprintf")
这样也不会影响到其他需要使用该宏的代码。
4. - 其他链接
扩展阅读:
C之 #pragma(二十二)
https://blog.51cto.com/u_12810168/2103680pragma编译指令大全(上)
pragma编译指令大全(下)
参考链接: