今天同事問了我一個問題,他make的時候報錯,「第201行:dereferencing pointer to incomplete type」,我隨即查閱了不少資料,也沒看出個因此然。最後問題獲得瞭解決,也懂得了原理,遂記錄一下。測試
他的問題具體是這樣。spa
#include <netinet/ip_icmp.h> ... struct icmp* aaa; aaa = (struct icmp*)malloc(sizeof(struct icmp)); //假設是第200行; aaa->icmp_type=1; //假設是201行; ...
make的時候第201行報錯:dereferencing pointer to incomplete type。code
首先說一下這個報錯的意思,通俗的說就是,試圖訪問該pointer指向的變量,卻發現該變量是一個不完整的類型,多出錯於訪問結構體聯合體的成員。從代碼中可看出來,是從201行開始才真正的訪問icmp_type指向的變量,200行還沒訪問。遞歸
因而我就猜測,是否是struct icmp沒有定義呢?遂粗略的查看了/usr/include/netinet/ip_icmp.h文件,發現有struct icmp的定義。很奇怪,不是嗎?通過寫了一些demo測試,最終的結論是,確實沒有struct icmp的定義!ip
看到這裏,更奇怪了。爲何是這樣的結論呢?細看/usr/include/netinet/ip_icmp.h文件,會發現struct icmp的定義被包含在一個宏裏面j,以下面所示:ci
... #ifdef __USE_BSD ... struct icmp { ... } ... #endif /*END OF ifdef __USE_BSD*/ ...
看到這裏應該就明白了,編譯的時候,若是編譯命令 gcc ...裏面沒有加入 -D__USE_BSD的話,那麼struct icmp的定義是不會被include進來的,因此就致使了前面的第201行報錯:dereferencing pointer to incomplete type,也就是這樣致使我開始一直想不明白,明明有定義,爲什麼卻說是不完整的類型。因而爲了驗證這個結論,我寫了一個小demo來測試,發現加 -D__USE_BSD就編譯經過,不然就編譯不經過。編譯
在解決這個問題的過程當中,我寫了很多demo,,下面總結一下。class
1.若是報錯「dereferencing pointer to incomplete type」,先試圖找一下該行的那個結構體變量的定義是否能找到,可以使用grep "struct xxx" /usr/include -R命令遞歸搜索/usr/include目錄,如找到,可在.c文件中#include,若是是非標準頭文件就要在編譯命令中加入-I頭文件目錄,例如(-I/usr/local/xxx/include)。變量
2.若是#include以後仍然報錯「dereferencing pointer to incomplete type」,試圖仔細查看該文件,查看該結構體的定義是否被某個編譯宏給包裹了,若是確實處於某個編譯宏的包裹內,在編譯命令裏面增長 -D編譯宏(如-D__USE_BSD)原理
通過上面兩個步驟之後,基本上能解決「dereferencing pointer to incomplete type」報錯了。
2012年7月20日17:01:59