代码之家  ›  专栏  ›  技术社区  ›  Renan Lopes

在C中,修复来自不同库的冲突类型的标准方法是什么?

  •  0
  • Renan Lopes  · 技术社区  · 7 年前

    我正在尝试将第三方库包括到 C 重新定义 冲突类型 错误,因为它具有同名的typedef结构。

    在阅读了SO中的一些答案后,我尝试加入警卫,显然直接更改了页面上的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;
                    ^
    

    我想知道解决这个问题的标准方法是什么,而不是改变 文件

    1 回复  |  直到 7 年前
        1
  •  3
  •   John Bollinger    7 年前

    C只有一个用于结构标记的命名空间,其中还包含联合和枚举的标记。不能在同一范围内使用具有相同标记的两种不同结构类型。有一个不同的命名空间包含 typedef 除其他事项外,一个类型名在任何给定范围内只能表示一件事。

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

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

    struct stack_item 和/或类型定义 stack_item 为了一个,和 struct queue_item 和/或 queue_item 另一方面。请注意,这可能会产生比您想要的更广泛的影响——例如,更改结构成员名称。此外,尽管它有很好的工作机会,但调用任何具有从原始结构类型的实例派生或包含原始结构类型的实例的参数或返回类型的函数在技术上是不符合要求的(有一些警告)。

    如果不起作用,您还可以考虑手工执行等效编辑,以生成只供项目使用的头文件的本地版本。这将允许您更精确地了解更改的内容,但使用这些头仍然会遇到上述一致性问题。

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

    推荐文章