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

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

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

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


2
可以给预处理器项命名,以便其他模块不会覆盖它们(按照惯例,而非强制执行)。我认为你所要求的是不可能的。 - mah
2个回答

8
C++语言没有提供自动处理预处理器宏保存和恢复的方法。预处理器宏(不是从编译器或编译器命令行中定义的)在文件全局级别上工作,没有将宏限制于特定被#include的头文件的概念。
我的解决方案是创建一个新的头文件,为我需要的特定库提供接口包装,但没有任何宏依赖关系。然后在只包括有问题的头文件的源文件中实现这些包装。
您的编译器可能提供了一种扩展来使任务更简洁,但不是以我理解的完全自动化的方式。
GCC和Microsoft编译器支持推送和弹出宏指示 pragma。
为兼容微软Windows编译器,GCC支持#pragma push_macro("macro_name")和#pragma pop_macro("macro_name")。
#pragma push_macro("macro_name") 此指示将名为macro_name的宏的值保存到此宏的堆栈顶部。
#pragma pop_macro("macro_name") 此指示将名为macro_name的宏的值设置为该宏的堆栈顶部的值。如果macro_name的堆栈为空,则该宏的值保持不变。 GCC documentation

但是我将包含wrapper.hh,它将包含实现wrapper.cc,而wrapper.cc将包含conflictingheader.hh,因此最终我的文件仍将包含conflictingheader.hh。我有什么遗漏吗? - Marco Agnese
3
头文件不应包含源文件。 - jxh

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时才会考虑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接