l4m*_*mpi 6 c c++ gcc name-mangling anonymous-struct
我们有一个庞大的旧C++应用程序,其中包含许多遗留代码和一些用C编写的外部库.这些库很少更新 - 只有当我们发现错误并且供应商提供补丁时.这发生在上周有一个库,在集成新版本后,我们发现如果我们不在本地修改库(我们显然使用上一版本),我们的构建就会出现以下错误消息:
non-local function ‘static E* MyCls::myFct(<anonymous struct>*)’ uses anonymous type
Run Code Online (Sandbox Code Playgroud)
这是因为库声明了许多句柄类型,如下所示:
#define _Opaque struct {unsigned long x;} *
typedef _Opaque Handle;
typedef _Opaque Request;
Run Code Online (Sandbox Code Playgroud)
我们在一些类的函数签名中使用它们:
class MyCls {
public:
static void* myFct(Handle handle);
...
}
Run Code Online (Sandbox Code Playgroud)
这会产生上述错误,因为编译器无法为函数创建正确的名称标记名称,因为_Opaque结构没有名称.
我们当前的解决方法是修补库头文件,显式给结构命名:
//#define _Opaque struct {unsigned long x;} * //Replaced by typedef below!
typedef struct __Opaque {unsigned long x;} * _Opaque;
Run Code Online (Sandbox Code Playgroud)
这显然很糟糕,因为如果可能的话我们不想触摸库.另一个更糟糕的选择是将类型转换为void*所有函数签名并将它们转换回各自的类型.并且在纯C中重写每个受影响的函数是最糟糕的选择...
所以,我的问题是:有没有比修补图书馆更好的选择?我有一个简单的解决方案吗?解决这个问题的最佳方法是什么?
您可以通过对该行进行最小的更改来完成此操作#define,利用 7.1.3:8 中的规则,即由声明声明的 \xef\xac\x81rst typedef-name 被用于\n该类类型(或枚举类型)用于表示仅用于链接目的的类类型(或枚举类型):
#define MAKE_DUMMY2(line) dummy_ ## line\n#define MAKE_DUMMY(line) MAKE_DUMMY2(line)\n#define _Opaque struct {unsigned long x;} MAKE_DUMMY(__LINE__), *\nRun Code Online (Sandbox Code Playgroud)\n\n这给出了最小的联系Handle等Request。