避免重新定义预处理器变量

Avoid redefinition preprocessor variable

本文关键字:预处理 处理器 变量 定义 新定义      更新时间:2023-10-16

我有不同的预处理器变量,它们在不同的库中具有相同的名称。

为了避免冲突,我所做的是(在这个例子中,为了简单起见,只有一个冲突变量和一个头文件要包含):

#ifdef VAR
#define TEMPVAR VAR
#undef VAR
#endif   
#include "conflictingheader.hh" 
#ifdef VAR
#undef VAR
#endif
#ifdef TEMPVAR
#define VAR TEMPVAR
#undef TEMPVAR
#endif

是否有一种自动的方法来存储所有冲突的变量,取消定义并稍后恢复它们?

或者是否可以定义一个宏来执行这些操作?

c++语言没有提供自动处理预处理宏保存和恢复的方法。预处理器宏(不是从编译器或编译器命令行定义的)在文件全局级别上工作,并且没有将宏的作用域限制为特定头文件的概念,该头文件是#include d。

我处理这种问题的方法是创建一个新的头文件,为我需要的特定库的功能提供接口包装,但没有任何宏依赖。然后在只包含麻烦的头文件的源文件中实现包装器。

你的编译器可能会提供一个扩展,使任务不那么冗长,但不是完全自动化的方式,我理解你的意思。

GCC和Microsoft编译器支持push和pop宏。

为了兼容Microsoft Windows编译器,GCC支持#pragma push_macro("macro_name")#pragma pop_macro("macro_name")

#pragma push_macro("macro_name")
该pragma将命名为macro_name的宏的值保存到该宏的堆栈顶部。

#pragma pop_macro("macro_name")
该pragma将名为macro_name的宏的值设置为该宏堆栈顶部的值。如果macro_name的堆栈为空,宏的值保持不变。

<<p> <子> GCC文档/订阅>

没有标准的方法。@jxh有一个很棒的非标准方式。它不起作用的原因是宏在展开之前根本不会被求值,它们在另一个宏定义中使用时不会被求值。

#define MY_MACRO  VAR
#define MY_STR_MACRO2(M) # M
#define MY_STR_MACRO(M) "MY_MACRO = " MY_STR_MACRO2(M) "n"
    printf(MY_STR_MACRO(MY_MACRO));  //writes "VAR"
#define VAR 4
    printf(MY_STR_MACRO(MY_MACRO)); //writes "4"
#undef VAR
    printf(MY_STR_MACRO(MY_MACRO));  //writes "VAR" again

在每一行printf上,它查看MY_MACRO并看到它是"VAR",然后查看VAR是否被定义为任何东西。有时是,有时不是。

所以当你尝试这个时:

#define TEMPVAR VAR

TEMPVAR中捕获的唯一东西是"VAR"任何VAR可能求值的东西此时都不考虑,直到它必须求值TEMPVAR