【发布时间】:2017-07-20 01:45:41
【问题描述】:
我有一个非常大的程序没有编译,我怀疑它与结构之间的循环依赖有关。当我像下面这样编码时,它不会编译
foo.h
#ifndef FOO
#define FOO
#include "bar.h"
typedef struct _foo Foo;
struct _foo{
Bar *bar;
}
#endif
bar.h
#ifndef BAR
#define BAR
#include "foo.h"
typedef struct _bar Bar;
struct _bar{
Foo *foo;
}
#endif
但如果我完全搞砸了我的设计并创建了一个 common.h 文件,并将所有结构声明放入其中,它似乎可以工作。
common.h
#ifndef COMMON
#define COMMON
typedef struct _foo Foo;
typedef struct _bar Bar;
#endif
foo.h
#ifndef FOO
#define FOO
#include "common.h"
#include "bar.h"
struct _foo{
Bar *bar;
}
#endif
bar.h
#ifndef BAR
#define BAR
#include "common.h"
#include "foo.h"
struct _bar{
Foo *foo;
}
#endif
这似乎是非常糟糕的设计。此外,我认为标头保护旨在防止由循环包含引起的问题。我应该使用 common.h 方法,还是我做错了什么导致我的第一个解决方案失败?
【问题讨论】:
-
循环包含总是错误的。
-
“标题保护旨在防止由循环包含引起的问题”。包含守卫旨在打破循环。这使得循环包含毫无意义(因为警卫无论如何都会阻止它)。但是,包含守卫并不能帮助您解决最初尝试通过使用循环包含来解决的依赖问题。
-
@AnT 那么为简单起见,将所有结构声明 dump 放在一个头文件中是否有意义?我担心的是我最终会得到一个 common.h 文件,其中声明的结构彼此无关
-
你的例子已经足够好了。只需假设
foo.h是较低级别的标头,bar.h是较高级别的标头。将foo.h包含到bar.h中(就像您现在所做的一样),但不要将bar.h包含到foo.h中。相反,只需将typedef struct _bar Bar;添加到foo.h。完毕。 (并且不要忘记结构类型声明末尾的分号)。 -
@AnT 如果我有两个大组件 A 和 B,每个组件都有 200 行长,我真的不想将它们组合成一个 400 行的文件。
标签: c struct c-preprocessor header-files