避免重新定义预处理器变量
Avoid redefinition preprocessor variable
我有各种预处理器变量,它们在不同的库中具有相同的名称。
为了避免冲突,我正在做的是(在示例中,为了简单起见,只有 1 个冲突变量和 1 个 header 要包含):
#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++ 语言不提供自动处理预处理器宏保存和恢复的方法。预处理器宏(不是从编译器或编译器命令行定义的)在文件全局级别上工作,并且没有将宏的范围限制为正在 [=10= 的特定 header 的概念]d.
我处理此类问题的方法是创建一个新的 header 文件,该文件为我需要的特定库的功能提供接口包装器,但没有任何宏依赖性。然后在只包含麻烦的 header 文件的源文件中实现包装器。
您的编译器可能会提供一个扩展来使任务不那么冗长,但不会按照我理解的方式完全自动化。
GCC 和 Microsoft 编译器支持 push 和 pop 宏编译指示。
For compatibility with Microsoft Windows compilers, GCC supports #pragma push_macro("macro_name")
and #pragma pop_macro("macro_name")
.
#pragma push_macro("macro_name")
This pragma saves the value of the macro named as macro_name
to the top of the stack for this macro.
#pragma pop_macro("macro_name")
This pragma sets the value of the macro named as macro_name
to the value on top of the stack for this macro. If the stack for macro_name
is empty, the value of the macro remains unchanged.
没有标准的方法来做到这一点。 @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
.
我有各种预处理器变量,它们在不同的库中具有相同的名称。
为了避免冲突,我正在做的是(在示例中,为了简单起见,只有 1 个冲突变量和 1 个 header 要包含):
#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++ 语言不提供自动处理预处理器宏保存和恢复的方法。预处理器宏(不是从编译器或编译器命令行定义的)在文件全局级别上工作,并且没有将宏的范围限制为正在 [=10= 的特定 header 的概念]d.
我处理此类问题的方法是创建一个新的 header 文件,该文件为我需要的特定库的功能提供接口包装器,但没有任何宏依赖性。然后在只包含麻烦的 header 文件的源文件中实现包装器。
您的编译器可能会提供一个扩展来使任务不那么冗长,但不会按照我理解的方式完全自动化。
GCC 和 Microsoft 编译器支持 push 和 pop 宏编译指示。
For compatibility with Microsoft Windows compilers, GCC supports
#pragma push_macro("macro_name")
and#pragma pop_macro("macro_name")
.
#pragma push_macro("macro_name")
This pragma saves the value of the macro named asmacro_name
to the top of the stack for this macro.
#pragma pop_macro("macro_name")
This pragma sets the value of the macro named asmacro_name
to the value on top of the stack for this macro. If the stack formacro_name
is empty, the value of the macro remains unchanged.
没有标准的方法来做到这一点。 @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
.