将守卫包括在C中

时间:2018-11-22 13:25:49

标签: c ifndef

我有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'

我猜它在标题声明中循环了吗?


编辑:

已修复合并两个文件的问题,从而简化了项目设计。如果您想要真正的修复,请在评论中查看。

3 个答案:

答案 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);
相关问题