5

I have various preprocessor variables which have the same name in different libraries.

In order to avoid conflicts, what I am doing is (in the example there is only 1 conflicting variable and 1 header to include for simplicity):

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

#include "conflictingheader.hh" 

#ifdef VAR
#undef VAR
#endif

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

Is there an automatic way to store all the conflicting variables, undefine them and restore them later?

Or is it possible to define a macro to perform these set of operations?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Marco Agnese
  • 349
  • 4
  • 15
  • 2
    It's possible to name your preprocessor items such that other modules will not step on them (by convention, not enforcement). I believe what you're asking for is not possible. – mah May 15 '15 at 18:22

2 Answers2

8

The C++ language does not provide an automated way to deal with preprocessor macro save and restore. Preprocessor macros (that are not defined from the compiler or the complier command line) work on a file global level, and there is no notion of restricting the scope of a macro to a particular header that is being #included.

The way I would deal with such an issue is create a new header file that provides interface wrappers to the functionality I need from that particular library, but without any macro dependencies. Then implement the wrappers in a source file that only includes that troublesome header file.


Your compiler may provide an extension to make the task a little less verbose, but not fully automated in the way that I understand you to mean.

GCC and Microsoft compilers support push and pop macro pragmas.

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.

GCC documentation

jxh
  • 69,070
  • 8
  • 110
  • 193
  • But then I will include the wrapper.hh which will include the implementation wrapper.cc which will include conflictingheader.hh so at the end my file will still include conflictingheader.hh. Am I missing something? – Marco Agnese May 15 '15 at 18:40
  • 3
    Header files should not include source files. – jxh May 15 '15 at 18:41
0

There is no standard way to do it. @jxh has a great non-standard way. The reason it doesn't work is that macros are not evaluated at all until they are expanded, they are not evaluated when used in another macro definition.

#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

On each printf line, it looks at MY_MACRO and sees that it is "VAR" and then looks to see if VAR is defined to anything. Sometimes it is, sometimes it isn't.

So when you try this:

#define TEMPVAR VAR

The only thing that is captured in TEMPVAR is "VAR" Anything that VAR might evaluate to is not considered at this point and won't be until it has to evaluate TEMPVAR.

IronMensan
  • 6,761
  • 1
  • 26
  • 35