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

时间:2015-05-15 18:19:37

标签: c++ variables c-preprocessor redefine

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

为了避免冲突,我正在做的是(在示例中,为简单起见,只有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 个答案:

答案 0 :(得分:8)

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

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

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

GCC和Microsoft编译器支持推送和弹出宏编译指示。

  

为了与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的堆栈为空,则宏的值保持不变。

     

<子> GCC documentation

答案 1 :(得分: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