5

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

为了避免冲突,我正在做的是(在示例中,为简单起见,仅包含 1 个冲突变量和 1 个标头):

#ifdef VAR
#define TEMPVAR VAR
#undef VAR
#endif   

#include "conflictingheader.hh" 

#ifdef VAR
#undef VAR
#endif

#ifdef TEMPVAR
#define VAR TEMPVAR
#undef TEMPVAR
#endif

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

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

4

2 回答 2

8

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

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


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

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

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

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

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

GCC 文档

于 2015-05-15T18:27:10.623 回答
0

没有标准的方法来做到这一点。@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

于 2015-05-15T20:05:51.917 回答