How to "disable" macros imported from C-Header

You could use the #ifdef and #undef preprocessor directives to detect the functions you want to call in C++, and disable the colliding macros declared in the C-header


You could create a "wrap_c_library.h" which is something like:

#ifndef WRAP_C_LIBRARY_H
#define WRAP_C_LIBRARY_H

#include "c_library.h"

#undef TROUBLESOME_MACRO_FROM_C_LIBRARY

#endif // WRAP_C_LIBRARY_H

Potentially (not sure how well this will work in practice) #undef doesn't have to mean manual work - you could auto-generate a second file to include that #undefs all of the definitions from the first header.

e.g. given this header:

#define A(X, Y) [X ; Y]
#define B(X, Y) {X...Y}
#define C this is C
#define D this is D

...run the following short script:

gcc -undef -dN -E foo.h > undef_foo.h
sed -i ".bak" 's/#define[ \t]\([A-Za-z0-9_]*\)/#undef \1/g' undef_foo.h
gcc -undef -dD -E - < /dev/null >> undef_foo.h
sed -i ".bak" '/#[du]/!d' undef_foo.h

...to produce this counter-header:

#undef __STDC__
#undef __STDC_HOSTED__
#undef __DYNAMIC__
#undef A
#undef B
#undef C
#undef D
#define __STDC__ 1
#define __STDC_HOSTED__ 1
#define __DYNAMIC__ 1

The basic idea: get a list of all definitions that are a consequence of including foo.h. The -undef -dN parameters to GCC minimize the amount of system-provided stuff that will be included in this list (down to three for me, not sure how consistent this is), to minimize the collateral and simplify the output. Then replace all #define lines with equivalent #undef lines (-dN makes this easier by not listing the replacements). Then append whatever few system-defined macros GCC still included to the end of the file, so their values are restored. Finally, remove all directives from the file that are not #define or #undef.

Usage:

#include "foo.h"
#include "undef_foo.h"

A(1, 2)
B(3, 4)
C
D

Run through gcc -E and observe the macros not expanding.

Someone with better scripting skills can probably make this a lot better, but that's the basic idea.


You already know about the #undef option, which would do what you need.

There is another option however. You could completely hide the fact that your A uses library C from your users: Define your own types and interface in the header and class definition of A and remove the library include from your A header. Then in your implementation file you can include the library header and utilize the library in whatever manner is needed, all the while hiding the include of the c_library.h from your users. This has the added advantage of reducing the coupling between your class users, your class, and the library that it depends on.