今天下午遇到乙個標頭檔案相互包含而導致的編譯問題,花了我不少時間去除錯沒找到問題,最後晚上跟師兄討論不少時間,突然有所頓悟!
我把問題脫離於專案簡單描述一下:我寫了乙個函式bool func(classa* ca)
需要加到專案中,我就把這個函式的宣告放到head1.h
中,函式引數型別 classa 定義在另乙個標頭檔案head2.h
中,因此我需要在head1.h
中包含head2.h
;而head2.h
中之前又包含了head1.h
,這樣就構成了一種標頭檔案相互包含的場景。再加上一些其它的宣告與定義,就構成了這樣的乙個檔案結構:
#ifndef __head_1_h__#define __head_1_h__
#include "head2.h"
#define var_macro 1
//define a macro, which used in head2.h
bool
func
(classa*ca
);//classa is defined in head2.h
#endif
#ifndef __head_2_h__#define __head_2_h__
#include "head1.h"
class
classa
;//macro var_macro is defined in head1.h
...//other members and functions
};#endif
那麼,現在另有兩個原始檔
#include "head1.h"//... some source code
#include "head2.h"//... some source code
整個專案會分別編譯這兩個原始檔,編譯完之後會報錯,大致意思是 classa 和 var_macro 沒有定義,那麼問題就比較奇怪了,每個標頭檔案都分別引用了另乙個標頭檔案,為什麼會出現未定義呢?
我們都知道 c/c++ 中標頭檔案開始習慣使用#ifndef ... #define ... #endif
這樣的一組預處理識別符號來防止重複包含,例如上面的問題中我也使用了,如果不使用的話,兩個標頭檔案相互包含,就出現遞迴包含。這個很好理解就不多敘。
回到問題本身,我在微博上貼出了這個問題,有人說在head1.h
的函式前加上classa a;
的前置宣告,至於為什麼要加,估計很多人都沒理解...
對於source1.cpp
,它包含了標頭檔案head1.h
,那麼在編譯之前,在source1.cpp
中展開head1.h
,而head1.h
又包含了head2.h
, 那麼也展開它,這時source1.cpp
就變成類似下面這樣:
classclassa
;//macro var_macro is defined in head1.h
...//other members and functions
};#define var_macro 1
//define a macro, which used in head2.h
bool
func
(classa*ca
);//classa is defined in head2.h
//... source1.cpp source code
看到沒,這地方 func 函式之前有 classa 型別的定義,根本沒必要像有些人說的那樣加上classa ca;
這樣的前置宣告。
我們再展開source2.cpp
看看:
#define var_macro 1//define a macro, which used in head2.h
bool
func
(classa*ca
);//classa is defined in head2.h
class
classa
;//macro var_macro is defined in head1.h
...//other members and functions
};//... source2.cpp source code
這時問題就很清楚了,func 函式宣告之前並沒有發現 classa 型別定義,該定義在函式宣告的後面,這時候如果能在head1.h
的函式宣告之前加上classa ca;
的前置宣告,就不會在編譯的時候報找不到 classa 的定義的錯誤了。
再回到source1.cpp
展開的原始碼看看,是不是一下子明白了為什麼報找不到 var_macro 的定義的錯誤了?修改方法也簡單,把巨集定義拉到#include "head2.h"
語句之前就 ok 了。
現在回頭想想這個問題,其實是個非常簡單的標頭檔案包含的問題,如果了解一些編譯器的預編譯過程,錯誤原理也很簡單。但為什麼我卡在這個問題很長時間,原因有以下幾點:
總的來說,遇到問題不要慌,保持大腦清醒,把加一行或減一行**期望就能碰運氣編譯通過的時間拿來分析問題更有效,解決問題之後一定確定自己是否知其然亦知其所以然!
google找了一圈,沒找到有價值的資料....
C C 中標頭檔案相互包含引發的問題
今天下午遇到乙個標頭檔案相互包含而導致的編譯問題,花了我不少時間去除錯沒找到問題,最後晚上跟師兄討論不少時間,突然有所頓悟!我把問題脫離於專案簡單描述一下 我寫了乙個函式bool func classa ca 需要加到專案中,我就把這個函式的宣告放到head1.h中,函式引數型別 classa 定義...
C C 中標頭檔案相互包括引發的問題
今天下午遇到乙個標頭檔案相互包括而導致的編譯問題,花了我不少時間去除錯沒找到問題。最後晚上跟師兄討論不少時間,突然有所頓悟!我把問題脫離於專案簡單描寫敘述一下 我寫了乙個函式bool func classa ca 須要加到專案中,我就把這個函式的宣告放到head1.h中,函式引數型別 classa ...
c 中標頭檔案的相互依賴引發的問題
先上 摘自essential c triangular.h include triangular iterator.h class triangular triangular iterator.h include triangular.h class triangular iterator inli...