我有这段代码:
main.h
#ifndef MAINH
#define MAINH
...
#include "my_struct.h"
void some_func(my_structure *x);
...
#endif
和
my_struct.h
#ifndef UTILSH
#define UTILSH
...
#include "main.h"
...
typedef struct abcd {
int a;
} my_structure;
...
#endif
但是当我尝试编译时,我得到了这个:error: unknown type name ‘my_structure’
知道为什么吗?
答案 0 :(得分:19)
由于您订购了包含的方式,编译器会在看到void some_func(my_structure *x);
之前看到typedef struct abcd { int a; } my_structure;
。
我想。
让我们一起来看看。
假设首先处理my_struct.h
,我们会得到以下事件序列:
UTILSH
已定义MAINH
已定义UTILSH
已定义,我们不再处理my_struct.h
,因此未处理typedef void some_func(my_structure *x);
正在处理中。因此,在预处理之后,编译器会看到以下声明序列:
...
void some_func(my_structure *x);
...
typedef struct abcd {...} my_structure;
坏juju。您需要在my_structure
中使用main.h
的前向声明,或者您需要打破该循环依赖(这是更受欢迎的选项)。 main.h
my_structure.h
实际使用的是main.h
中的任何内容吗?如果是这样,您需要将其分解为my_structure.h
和{{1}}都包含的单独文件。
答案 1 :(得分:5)
您创建了一个循环标题包含。循环包含从未实现任何目标。这是无限的。 #ifndef
包含守卫将在某个不可预测的点处打破无限包含圈(取决于首先包含在.c
文件中的哪个头)。这就是你的情况。基本上,您的循环包含被“解决”为包括main.h
第一和my_struct.h
秒。这就是main.h
对my_struct
类型一无所知的原因。
同样,循环包含永远不会实现任何目标。摆脱循环包含。按层次结构设计标题结构:较低级别的标题包含在较高级别的标题中,但从不相反。在您的情况下,my_struct.h
可能是较低级别的标头,这意味着您必须停止将main.h
包括在my_struct.h
中。重新设计标题,以便my_struct.h
不再需要main.h
。
答案 2 :(得分:3)
在main.h
定义my_struct.h
之前,错误消息来自my_structure
。您应该重新考虑自main.h
和my_struct.h
相互包含的包含路径。
您可能希望main.h
文件只包含my_struct.h
,而不是my_struct.h
包含任何内容。你实际上是在指示你的C编译器有一个无限的共同包含循环。