今天下午遇到乙個標頭檔案相互包括而導致的編譯問題,花了我不少時間去除錯沒找到問題。最後晚上跟師兄討論不少時間,突然有所頓悟!
我把問題脫離於專案簡單描寫敘述一下:我寫了乙個函式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 了。
如今回頭想想這個問題。事實上是個非常easy的標頭檔案包括的問題。假設了解一些編譯器的預編譯過程,錯誤原理也非常easy。
但為什麼我卡在這個問題非常長時間,原因有下面幾點:
總的來說。遇到問題不要慌,保持大腦清醒,把加一行或減一行**期望就能碰運氣編譯通過的時間拿來分析問題更有效,解決這個問題之後一定確定自己是否知其然亦知其所以然!
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...