问题描述
A.h
#ifndef __A_H_
#define __A_H_
#include <B.h> // contains foo_t
typedef struct {
foo_t foo;
...
} baz_t;
#endif
B.h
#ifndef __B_H_
#define __B_H_
#include <A.h> // contains baz_t
typedef struct {
...
} foo_t;
extern int useful_func(baz_t d);
#endif
当我编译此B.h时,他拒绝编译抱怨error: unkNown type name 'baz_t'
我假设此错误是由于两个文件之间的循环依赖性所致。但是我想知道如何转发声明baz_t
来解决这个问题?我找到了与结构之间的循环依赖关系有关的答案。但是我不确定如何解决这个问题。我希望在这里提供一些帮助。我正在寻找严格的C99解决方案。
编辑
- 我以前忘了提及这一点,但是我已经使用过包含卫兵。
- 用户KamilCuk建议的一个非常明显的解决方案是将
useful_func
移至A.h
。我也遇到过这种情况,但是不幸的是,软件组织明智的useful_func
属于B.h
。这个问题也可能反映出设计不佳。
解决方法
您可以如下使用前向声明:
Course
然后在B.h上正常使用
也就是说,如果您在用作接口的第三个标头上定义所有内容,则可以避免循环依赖。这样会更清洁,但并非总是可能。
,通常,将传递指向结构的指针,而不是按值传递它们。如果可以接受,那么事情就很容易了,因为C编译器将接受一个声明:
void doSomethingWithAFoo(struct foo *it);
,不考虑他们是否对struct foo
有任何定义。确实,编译器甚至会接受 definitions 之类的函数:
void doSomethingWithAFooTwice(struct foo *it)
{
doSomethingWithAFoo(it);
doSomethingWithAFoo(it);
}
无需知道或关心是否定义struct foo
,在何处或如何进行定义。
请注意,使用struct tag
语法而不是typedef名称的优势在于,使用struct标记语法的原型不需要声明或定义不能多次无害地声明的任何内容。