We have a big, old C++ application with a lot of legacy code and a few external libraries written in C. These libraries are very rarely updated - only if we find a bug and the vendor supplies a patch. This happened last week with one library, and upon integrating the new version we found out that if we don't modify the library locally (which we apparently did with the last version) our build breaks with this error message:
non-local function ‘static E* MyCls::myFct(<anonymous struct>*)’ uses anonymous type
This is due to the library declaring a number of handle types like this:
#define _Opaque struct {unsigned long x;} *
typedef _Opaque Handle;
typedef _Opaque Request;
which we use on our side in some classes' function signatures:
class MyCls {
public:
static void* myFct(Handle handle);
...
}
This produces the error above because the compiler can't create a proper name-mangled name for the function(s) as the _Opaque struct has no name.
Our current workaround for this is to patch the library header file, explicitly giving the struct a name:
//#define _Opaque struct {unsigned long x;} * //Replaced by typedef below!
typedef struct __Opaque {unsigned long x;} * _Opaque;
This is obviously bad because we don't want to touch the library if possible. Another even worse option would be to convert the types to void*
in all function signatures and cast them back to their respective types. And there's the worst option to rewrite every affected function in pure C...
So, my question is: Is there any better option than patching the library? Is there an easy solution I am overlooking? What would be the best way to solve this?
You can accomplish this with a minimal change to the
#define
line, exploiting the rule in 7.1.3:8 that the first typedef-name declared by the declaration to be that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only:This gives
Handle
andRequest
etc. minimal linkage.