我有2个头文件,它们必须彼此包含。
config.h:
#ifndef CONFIG
#define CONFIG
#include "debug.h"
typedef struct Config_t {
/* some stuff */
} Config;
#endif
debug.h
#ifndef DEBUG
#define DEBUG
#include "config.h"
void somePrintingFunction(Config* conf);
#endif
这是我得到的错误:
debug.h:错误:未知类型名称'Config'
config.c:警告:函数'somePrintingFunction'的隐式声明
debug.h:错误:未知类型名称'Config'
我猜它在标题声明中循环了吗?
编辑:
已修复合并两个文件的问题,从而简化了项目设计。如果您想要真正的修复,请在评论中查看。
答案 0 :(得分:4)
当config.h
包含debug.h
时,debug.h
将尝试包含config.h
,但是由于已经定义了CONFIG
保护宏,因此追溯“ config.h
中的“”将被跳过,并且解析将在下一行继续:
void somePrintingFunction(Config* conf);
未定义Config
类型。
正如StoryTeller所指出的,您可以通过向前声明Config_t
结构来打破相互依赖性:
struct Config_t;
void somePrintingFunction(struct Config_t* conf);
自C11起,您也可以执行typedef
,因为C11可以处理重复的typedef,只要它们引用相同的类型即可。
typedef struct Config_t Config;
void somePrintingFunction(Config* conf);
(聚集(结构或联合)的前向声明不允许您声明这些类型的对象(除非已提供完整的定义),但是由于C保证指向结构或联合的所有指针必须看起来相同,它们足以让您开始使用指向这些类型的指针。)
答案 1 :(得分:3)
问题在于循环包含。在声明结构之前,实际上是在包含函数。
可以说您包含config.h
(假设预处理器执行以下操作删除了错误的包含a.h
:
#include "debug.h"
typedef struct Config_t {
/* some stuff */
} Config;
并定义符号CONFIG
,以便此文件不会被包含两次。然后评估其余的内容:
#include "config.h"
void somePrintingFunction(Config* conf);
typedef struct Config_t {
/* some stuff */
} Config;
,并定义符号DEBUG
。由于定义了符号CONFIG
,因此它将第二次不包含config.h
,因此它已完成。现在注意函数的声明在结构的声明之前。为了解决这个问题,使用像这样的前向声明
#include "config.h"
struct Config_t;
void somePrintingFunction(struct Config_t* conf);
因此,编译器在使用Config
之前就知道它是什么。只需记住要在c
文件中定义所有使用预声明的结构或类的函数,因为该预声明的对象尚未定义,而是将在c
文件中。
编辑:我要提一下,循环包含并不是一件好事,您通常可以找到另一种解决方案,其风险较小。
答案 2 :(得分:2)
debug.h
不需要其他标题。您可以单独使用Config_t
的前向声明来定义该函数就可以了
struct Config_t;
void somePrintingFunction(struct Config_t* conf);