我深知前路風(fēng)雨,但我依然微笑前行 ;)
問題:
頭文件交叉包含是否會導(dǎo)致遞歸包含c語言頭文件下載,導(dǎo)致編譯出錯?如果不會因為遞歸包含出錯,那么交叉包含是不是完全沒問題? 1.1 頭文件交叉包含是否會導(dǎo)致遞歸包含,導(dǎo)致編譯出錯?(無#)
假若頭文件a包含了頭文件b、頭文件b又包含了頭文件a,那么在#頭文件a的時候,就可能會導(dǎo)致遞歸包含,從而導(dǎo)致編譯出錯;
/* a.h */
#include "b.h"
#define A_H 1
/* b.h */
#include "a.h"
#define B_H 2
/* main.c */
#include
#include
#include "a.h"
#include "b.h"
void main()
{
printf("hello world!\n");
}
在下面編譯會報錯: 1.2頭文件交叉包含是否會導(dǎo)致遞歸包含,導(dǎo)致編譯出錯?(有#)
修改a.h、b.h兩個文件,main.c文件內(nèi)容不變。此時編譯正常通過:因此可以知道,當(dāng)頭文件相互包含時,只要有預(yù)處理#就可以保證理論上不會出錯。
/* a.h */
#ifdef __A_H_
#define __A_H
#include "b.h"
#define A_H 1
#endif
/* b.h */
#ifndef __B_H_
#define __B_H
#include "a.h"
#define B_H 2
#endif
1.3 如果不會因為遞歸包含出錯,那么交叉包含是不是完全沒問題?
從上面的頭文件內(nèi)容可以看出,雖然兩個頭文件相互包含,但是兩個頭文件內(nèi)容并不相互引用。因此編譯不會出現(xiàn)問題。但是如果像下面文件,頭文件變量又相互引用,則編譯會出現(xiàn)變量未知錯誤
a.h:9:9: error: type name ‘B_H’
/* a.h */
#ifndef __A_H_
#define __A_H_
#include "b.h"
typedef struct _A_H{
int a;
} A_H;
int fun(B_H *ptr);
#endif
/* b.h */
#ifndef __B_H_
#define __B_H_
#include "a.h"
typedef struct _B_H{
A_H b;
} B_H;

#endif
/* main.c */
#include
#include "b.h"
#define CC DD
#define DD 2
void main()
{
printf("hello world!\n");
}
使用 ‘gcc -E main.c > tmp’ 將main.c只做預(yù)處理,可以看到預(yù)處理后的文件內(nèi)容為:所以是因為變量定義的順序問題導(dǎo)致問題。
/* tmp 部分內(nèi)容*/
# 1 "b.h" 1
# 4 "a.h" 2
typedef struct _A_H{
int a;
} A_H;

int fun(B_H *ptr);
# 4 "b.h" 2
typedef struct _B_H{
A_H b;
} B_H;
# 3 "main.c" 2
int main()
{
printf("hello world!\n");
return 0;
}
1.4 但是將b.h文件中的結(jié)構(gòu)體加上又可以編譯成功了!!!
此時會出現(xiàn)警告:結(jié)構(gòu)體隱性申明
a.h:9:16: : ‘ _B_H’ list [ by ]
/* a.h */
#ifndef __A_H_

#define __A_H_
#include "b.h"
typedef struct _A_H{
int a;
} A_H;
int fun(struct _B_H *ptr);
#endif
/* b.h */
#ifndef __B_H_
#define __B_H_
#include "a.h"
typedef struct _B_H{
struct _A_H b;
} B_H;
#endif
總結(jié)
頭文件相互包含,而且變量又相互引用。此時應(yīng)該將其中一個頭文件拆成兩個頭文件b1.h、b2.hc語言頭文件下載,b1.h讓原來的a.h包含;b2.h用來包含a.h。不要使兩個頭文件變量相互引用引用的設(shè)計方式出現(xiàn)。
從上面main.c內(nèi)容可以看出宏定義的順序可以不按順序出現(xiàn),編譯也不會出錯。