如果我正确理解了您的问题,您将得到如下信息:
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 ,然后包含derpbarfunctions.h,然后定义其函数。
derpbarfunctions.h首先包含derpfoostructs.h和derpbarstructs.h ,然后包含derpfoofunctions.h,然后定义其函数。
derp.c 包括derpfoostructs.h 和derpbarstructs.h ,然后包括derpfoofunctions.h 和derpbarfunctions.h,然后继续做它需要做的任何其他事情。
这满足了两个期望的要求。它消除了循环依赖,并且仍然保持两个逻辑分离的代码单元的逻辑分离。当您从一个项目更改为另一个项目时,您需要编辑两个文件而不是一个,但它至少使可变代码与不可变代码分开。那是我找到的唯一解决方案。
希望这有帮助。祝你的项目好运。