簡體   English   中英

將守衛包括在C中

[英]Include Guards in C

我有2個頭文件,必須包含另一個頭文件。

config.h:

#ifndef CONFIG
#define CONFIG

#include "debug.h"

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

調試

#ifndef DEBUG
#define DEBUG

#include "config.h"

void somePrintingFunction(Config* conf);
#endif

這是我得到的錯誤:

debug.h:錯誤:未知類型名稱“ Config”

config.c:警告:函數“ somePrintingFunction”的隱式聲明

debug.h:錯誤:未知類型名稱“ Config”

我猜它在頭聲明中循環了嗎?


編輯:

修復了合並兩個文件的問題,從而簡化了項目設計。 如果您要進行真正的修復,請在注釋中簽入。

config.h包含debug.hdebug.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保證所有指向結構或聯合的指針必須看起來相同,所以它們就足夠了讓您開始使用指向這些類型的指針。)

問題在於循環包含。 在聲明結構之前,實際上是在包含函數。 可以說您包含config.h (假設您刪除了錯誤的包含ah ,預處理器會這樣做:

#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文件中。

編輯:我應該提一下,循環包含並不是一件好事,您通常可以找到另一種解決方案,這種解決方案的風險較小。

debug.h不需要其他標頭。 您可以單獨使用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