As others already mentioned in comments, the best option is to write another C API layer around that stuff, that uses the other API only internally.
Anything related to this offending struct definition should be exported through opaque pointers only.
In C++ you can use the cleaned up C-API then.
Here's a small sketch:
ThirdParty.h (contains offending code to compile with c++)
#ifdef __cplusplus extern "C" { #endif struct something_t { ... sometype class; }; struct something_t* CreateSomething(); // Does memory allocation and initialization void DoSomething(struct something_t* something); #ifdef __cplusplus } #endif
MyApiWrapper.h
#ifdef __cplusplus extern "C" { #endif typedef void* psomething_t; struct psomething_t MyCreateSomething(); // Does memory allocation and initialization void MyDoSomething(psomething_t something); #ifdef __cplusplus } #endif
MyApiWrapper.c
#include "ThirdParty.h" struct psomething_t MyCreateSomething() { psomething_t psomething = (psomething_t)CreateSomething(); return psomething; } void MyDoSomething(psomething_t something) { DoSomething((struct something_t*)psomething); }
Regarding your considered solutions
- I could ask the upstream project to rename the variable, but that may be difficult
You certainly should report that bug to let them know. If it's a git-hub hosted project prepare a pull request.
Anyways be prepared that they might not be responsive timely, and you should always have the above mentioned "plan B". It will work regardless ...
- I could redefine class in the header using the preprocessor: #define class class_ Are there any side effects?
It could be a viable way, if any place where this particular symbol (class) appears is plain c code and no other parts of the 3rd party c code (e.g. as library) depends on that symbol (which is unlikely).
class. The best long-term solution (IMO) is 2.