我正在尝试将第三方库包含在.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文件中的定义
C 只有一个用于结构标记的命名空间,其中还包含联合和枚举的标记。 不能在同一作用域中使用具有相同标记的两种不同的结构类型。 有一个不同的命名空间包含typedef
ed 标识符等,但同样,一个类型名称在任何给定范围内只能表示一件事。
但是,在实践中,结构名称仅在编译时才有意义。 如果您使用的是第三方库的打包预编译版本,那么您可能只需要担心标头。您可以使用预处理器更改程序翻译单元范围内的一个或两个标记。 例如
#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
用于另一个。 请注意,存在产生比您希望的更广泛的影响的风险 - 例如,更改结构成员名称。 此外,尽管它有很好的工作机会,但在技术上,调用任何具有从原始结构类型派生或包含原始结构类型实例的参数或返回类型的函数是不合规的(有一些警告)。
如果这不起作用,您还可以考虑手动执行等效的编辑,以生成仅供项目使用的标头的本地版本。 这将使您能够更准确地了解更改的内容,但使用这些标头仍然会遇到上述一致性问题。
如果您必须在同一个翻译单元中使用这两个库,并且希望确保您的代码符合标准,那么您就不走运了。 唯一符合的替代方法是修改并重建一个或两个库,以便它们不再存在名称冲突。