在 C 中包含守卫

Include Guards in C

我有 2 个 header 个文件必须包含另一个文件。

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: error: unknown type name 'Config'

config.c: warning: implicit declaration of function 'somePrintingFunction'

debug.h: error: unknown type name 'Config'

我猜它在 header 声明中循环?


编辑:

已修复合并两个文件的问题,从而简化项目设计。如果你想要一个真正的修复检查评论。

debug.h 不需要另一个 header。您可以单独使用 Config_t

的前向声明来定义该函数
struct Config_t;
void somePrintingFunction(struct Config_t* conf);

问题在于循环包含。在声明结构之前,您实际上已经包含了函数。 假设您包含 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 文件中定义所有使用预声明结构或 class 的函数,因为预声明对象尚未定义,但将在 c 文件中。

编辑:我要提一下,循环包含不是一件好事,您通常可以找到另一种风险较小的解决方案。

config.h 包含 debug.h 时,debug.h 将尝试包含 config.h 但由于 CONFIG 保护宏已经定义,追溯config.h 的 "include" 将被跳过,解析将在下一行继续:

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 保证所有指向结构或联合的指针必须看起来同样,它们足以让您开始使用指向这些类型的指针。)