Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling macro redefinition without modifying .h files ... C / C++ language

Tags:

c++

c

Background:

Let assume that I have two header files a.h and b.h.

a.h contains:

#define VAR 1

b.h contains:

#define VAR 2

Note: The name of both of the macro is same. Let say I have some file myFile.c which includes both of the header files i.e. a.h and b.h.

When I try to access VAR, I get a redefinition error of VAR.

In order to resolve this problem, I inserted #ifndef VAR statement in both a.h and b.h files to prevent this error. a.h file becomes

#ifndef VAR
  #define VAR 1
#endif

b.h file becomes

#ifndef VAR
  #define VAR 2
#endif

Note: The header file can contain multiple macros, not just one macro.

Problem:

Let's assume that a.h and b.h files are obtained from third party library. These files don't contain #ifndef VAR statement.

I am not allowed to change their header files.

Can I resolve macro 'VAR' redefinition error in myFile.c or myFile.cpp file which uses VAR macro?

I know I #undef VAR can be used to undefine a macro VAR. How can I selectively include VAR later in my program? i.e. on line 10 of myFile.c code I should be able to refer to VAR definition from a.h file, on line 15 of my code I should be able to refer to VAR from b.h file and on line 18 again I should be able to refer to VAR from a.h file.

In short, am I able to do macro polymorphism ? Given a name of header file, it should refer to macro definition present in that file.

I thought of using namespace trick to resolve an issue. Define first header file in namespace first and second header file in namespace second.

I tried defining two namespaces. First namespace contains #include a.h and second namespace contains b.h. However, namespace trick does not work with macro. When I tried to access firstns::VAR, compiler reports an error message.

Can you please suggest some way?

like image 261
user310119 Avatar asked Apr 06 '10 14:04

user310119


2 Answers

Macro expansion happens at the preprocessor level and is impervious to namespace use.

Are all macros that you want to use simple constants, not used in token concatenation etc.?

If so, then you can try something like the following to bridge the preprocessor/compiler gap and retain access to both the A and B definitions of VAR etc., if it suits your situation:

// ab_wrapper.h
#include <a.h>
static const int   A_VAR1 = VAR1;
static const char* A_VAR2 = VAR2;
#undef VAR1
#undef VAR2

#include <b.h>
static const int   B_VAR1 = VAR1;
static const char* B_VAR2 = VAR2;

// code.c
#include <ab_wrapper.h>
...
int x = A_VAR1;
int y = B_VAR1;
...
like image 51
vladr Avatar answered Oct 08 '22 20:10

vladr


You could include the problematic header files always via your own dedicated header files, where you can add the necessary #ifdef, #undef etc. macros to prevent redefinition errors. E.g.

wrapperToA.h
-----
#ifdef VAR
  #undef VAR
#endif

#include "a.h"

Update: @Vlad worked out the full solution in the meantime - kudos to him (and +1 :-)

like image 42
Péter Török Avatar answered Oct 08 '22 19:10

Péter Török