简体   繁体   English

将守卫包括在C中

[英]Include Guards in C

I have 2 header files that have to include one other. 我有2个头文件,必须包含另一个头文件。

config.h: 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

Here is the error I get: 这是我得到的错误:

debug.h: error: unknown type name 'Config' debug.h:错误:未知类型名称“ Config”

config.c: warning: implicit declaration of function 'somePrintingFunction' config.c:警告:函数“ somePrintingFunction”的隐式声明

debug.h: error: unknown type name 'Config' debug.h:错误:未知类型名称“ Config”

I guess it's looping in the header declaration? 我猜它在头声明中循环了吗?


Edit: 编辑:

Fixed in merging both files so simplify project design. 修复了合并两个文件的问题,从而简化了项目设计。 If you want a real fix check in comments. 如果您要进行真正的修复,请在注释中签入。

When config.h includes debug.h , debug.h will try to include config.h but since the CONFIG guard macro will already have been defined, the retroactive "include" of config.h will get skipped and the parsing will continue on the next line: config.h包含debug.hdebug.h将尝试包含config.h但是由于已经定义了CONFIG保护宏,因此将跳过config.h的追溯性“ include”,并且解析将继续进行。下一行:

void somePrintingFunction(Config* conf);

without the Config type having been defined. 没有定义Config类型。

As StoryTeller has pointed out, you can break the mutual dependency by forward declaring the Config_t struct: 正如StoryTeller所指出的,您可以通过向前声明Config_t结构来打破相互依赖性:

struct Config_t;
void somePrintingFunction(struct Config_t* conf);

Since C11, you can also do the typedef since C11 can handle duplicated typedefs as long as they refer to the same type. 从C11开始,您还可以执行typedef因为C11可以处理重复的typedef,只要它们引用相同的类型即可。

typedef struct Config_t Config;
void somePrintingFunction(Config* conf);

(Forward declarations of aggregates (structs or unions) don't allow you to declare objects of those types (unless a full definition has already been provided) but since C guarantees that all pointers to structs or unions must look the same, they are enough to allow you to start using pointers to those types.) (聚合(结构或联合)的前向声明不允许您声明这些类型的对象(除非已提供完整的定义),但由于C保证所有指向结构或联合的指针必须看起来相同,所以它们就足够了让您开始使用指向这些类型的指针。)

The problem with this is the circular inclusion. 问题在于循环包含。 You are actually including your function before you declare your structure. 在声明结构之前,实际上是在包含函数。 Lets say you include config.h (assuming you removed the wrong include ah the preprocessor does this: 可以说您包含config.h (假设您删除了错误的包含ah ,预处理器会这样做:

#include "debug.h"

typedef struct Config_t {
    /* some stuff */
} Config;

and defines the symbol CONFIG so that this file will not be included twice. 并定义了符号CONFIG以便此文件不会被包含两次。 Then it evaluates the remaining include: 然后评估剩余的内容:

#include "config.h"

void somePrintingFunction(Config* conf);


typedef struct Config_t {
    /* some stuff */
} Config;

and defines the symbol DEBUG . 并定义符号DEBUG Since symbol CONFIG is defined it will not include config.h a second time and thus it is finished. 由于已定义符号CONFIG ,因此它将不会第二次包含config.h ,因此它已完成。 Now notice how the declaration of the function is before the declaration of the structure. 现在注意函数的声明在结构的声明之前。 To solve this use a forward declaration like this 为了解决这个问题,使用这样的前向声明

#include "config.h"

struct Config_t;
void somePrintingFunction(struct Config_t* conf);

So the compiler knows what Config is before you use it. 因此,编译器在使用Config之前就知道它是什么。 Just keep in mind to define all functions that use a predeclared structure or class in the c file because the predeclared object is not a defined one yet but will be in the c file. 只需记住在c文件中定义所有使用预声明的结构或类的函数,因为该预声明的对象尚未定义,而是将在c文件中。

EDIT: I should mention that circular inclusion is not a good thing to do and you can usually find another solution which is less sanity risking. 编辑:我应该提一下,循环包含并不是一件好事,您通常可以找到另一种解决方案,这种解决方案的风险较小。

debug.h doesn't need the other header. debug.h不需要其他标头。 You can define that function just fine with a forward declaration of Config_t alone 您可以单独使用Config_t的前向声明来定义该函数

struct Config_t;
void somePrintingFunction(struct Config_t* conf);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM