解决循环依赖 - C

时间:2013-02-19 13:06:51

标签: c

我检查了SO的副本,但无法找到解决问题的确切方法。

我有一个头文件NvCommon.h,其中我使用枚举NV_DATA_TYPE。此枚举在另一个标头NvDefs.h中定义,其中我使用了NvCommon.h中的许多结构和枚举。由于循环依赖,我无法构建它。我知道forwrd declaring enum是不可能的。

在这种情况下可以做些什么?这是我设计的问题吗?我是否必须引入另一个头文件来解决这个问题?

我不是C专家。请帮我。我的设计可能有问题,我知道可以通过引入另一个头文件来修复此循环依赖。我想知道的是“是唯一的解决方法”。寻找备用解决方案(如果有)。

如果有用,我会发布完整的代码。

5 个答案:

答案 0 :(得分:11)

在自己的文件中定义枚举会很有用,如果你在这里这样做,你的问题就会消失。

答案 1 :(得分:6)

如果我理解你的问题,你就会得到这样的结论:

derpfoo.h:

#ifndef DERPFOO_H
#define DERPFOO_H

#include "derpbar.h"

typedef struct {
        char *nothing;
} FOO;

BAR foo (BAR derp) {
        return derp;
}

#endif

derpbar.h:

#ifndef DERPBAR_H
#define DERPBAR_H

#include "derpfoo.h"

typedef struct {
        char *nothing;
} BAR;

FOO bar (FOO derp) {
        return derp;
}

#endif

然后是一个简单的derp.c:

#include "derpfoo.h"
#include "derpbar.h"

int main (void) {
        return 0;
}

我的一位朋友刚才在一些SDL代码中向我提出了这个问题,我花了一段时间才明白他为什么要做他正在做的事以及如何合理地修复它。

将这样的代码分开的意图是derpfoo和derpbar在逻辑上是分开的,但它们也可能是相互依赖的。我发现这样一个最简单的解决方案就是将它们组合起来并根据解剖而不是逻辑分割它们:

derpstructs.h:

#ifndef DERPSTRUCTS_H
#define DERPSTRUCTS_H

typedef struct {
        char *nothing;
} FOO;

typedef struct {
        char *nothing;
} BAR;

#include "derpfunctions.h"

#endif

derpfunctions.h:

#ifndef DERPFUNCTIONS_H
#define DERPFUNCTIONS_H

#include "derpstructs.h"

BAR foo (BAR derp) {
        return derp;
}

FOO bar (FOO derp) {
        return derp;
}

#endif

仍然是一个简单的derp.c:

#include "derpstructs.h"
#include "derpfunctions.h"

int main (void) {
        return 0;
}

请注意,derpstructs.h在末尾包含derpfunctions.h 而不是在开头。严格来说,这不是必需的,但是如果你打算让它们相互包含,你必须在所有可能的包含路径中包含之后它们所依赖的结构定义。继续......

这个解决方案有效,但它并不完全坚持导致问题开始的原始理念 - 这两个部分在逻辑上是分开的,应该在代码中保留。

两者的答案是进一步分解所有内容,并进一步调整包含路径。

derpfoostructs.h包含derpbarstructs.h 首先,然后定义struct FOO,然后结束可选择包含derpfoofunctions.h和derpbarfunctions.h。

derpbarstructs.h包含derpfoostructs.h 首先,然后定义struct BAR,然后结尾可选择包含derpfoofunctions.h和derpbarfunctions.h。

derpfoofunctions.h包括derpfoostructs.h和derpbarstructs.h first ,然后包含derpbarfunctions.h,然后定义其功能。

derpbarfunctions.h包括derpfoostructs.h和derpbarstructs.h first ,然后包含derpfoofunctions.h,然后定义其功能。

derp.c包括derpfoostructs.h和derpbarstructs.h 然后包括derpfoofunctions.h和derpbarfunctions.h,然后继续做其他需要做的事情。

这满足了两个期望的要求。它消除了循环依赖性,并且仍然保持两个逻辑上独立的代码单元的逻辑分离。当您从一个项目更改为一个项目而不是一个项目时,您将获得两个要编辑的文件,但它至少使可变代码与不可变的代码保持一致。那是,这是我找到的唯一解决方案。

希望这有帮助。祝你的项目好运。

答案 2 :(得分:2)

循环依赖可能意味着您过度设计了界面。将两个文件合并到Nv.h.如果这很容易解决问题,这意味着您错误地设计了界面。

答案 3 :(得分:1)

Check this out

如何正确声明和定义变量,库,函数等。这可能是相关的。

答案 4 :(得分:1)

我尝试根据您的描述对此问题进行建模。在我的实现中,我测试了三件事(1)声明但未在NvDefs.h中定义NV_DATA_TYPE,(2)在NvDefs.h中声明和定义NV_DATA_TYPE,以及(3)在NvDefs.h中定义NV_DATA_TYPE,但声明它为NvCommon.h 。另外,正如您提供的描述,我在NvCommon.h中创建了一些结构并在NvDefs.h中访问了这些对象。在每种情况下 - 在头文件中有和没有警卫 - 编译和执行的代码都有正确的结果。

除了NV_DATA_TYPE枚举之外,您的循环依赖是否可能在头文件中的其他位置?