首页 > 解决方案 > 在 C 中修复来自不同库的冲突类型的标准方法是什么?

问题描述

我正在尝试将 3rd 方库包含到.c文件中,但它会给出重新定义冲突类型错误,因为它具有同名的 typedef 结构。

在阅读了 SO 中的一些答案后,我尝试包含警卫,显然直接更改.h文件上的 typedef 已经解决了这个问题。

例如(还必须更改函数返回类型)

// stack.h
typedef struct item stack_item;

// queue.h
typedef struct item queue_item;

但是,原始代码如下:

// stack.h
typedef struct item item;

// queue.h
typedef struct item item;

它抛出以下错误:

In file included from test.c:5:0:
Queues/queue.c:6:8: error: redefinition of ‘struct item’
 struct item {
        ^

In file included from Stacks/stack.c:4:0, from test.c:4:
Stacks/stack.h:6:16: note: originally defined here
 typedef struct item item;
                ^

我想知道解决此问题的标准方法是什么,而不是更改.h文件中的定义

标签: cstructconflicting-librariesname-collision

解决方案


C 结构标签只有一个命名空间,其中还包含联合和枚举的标签。您不能在同一范围内使用具有相同标记的两种不同结构类型。有一个不同的命名空间包含typedefed 标识符等,但同样,一个类型名称在任何给定范围内只能表示一件事。

但是,实际上,结构名称仅在编译时才有意义。如果您使用的是第三方库的打包、预编译版本,那么您可能只需要担心头文件。您也许可以使用预处理器在程序的翻译单元范围内更改一个或两个标签。例如,

#define item stack_item
#include <stack.h>
#undef item

#define item queue_item
#include <queue.h>
#undef item

然后,您的代码将使用struct stack_item和/或 typedefstack_item作为一个,struct queue_item和/或queue_item另一个。请注意,这可能会产生比您想要的更广泛的影响——例如,更改结构成员名称。此外,尽管它有一个不错的工作机会,但从技术上讲,调用任何具有派生自或包含原始结构类型实例或包含原始结构类型实例的参数或返回类型的函数是不符合规范的(有一些警告)。

如果这不起作用,您还可以考虑手动执行等效编辑以生成仅由您的项目使用的标头的本地版本。这将使您能够更准确地了解更改的内容,但是使用这些标头仍然会遇到上述一致性问题。

如果您必须在同一个翻译单元中使用这两个库,并且您想确保您的代码符合标准,那么您就不走运了。唯一符合要求的替代方法是修改和重建一个或两个库,以便它们不再有名称冲突。


推荐阅读