今天同事問了我一個問題,他make的時候報錯,“第201行:dereferencing pointer to incomplete type”,我隨即查閱了很多資料,也沒看出個所以然。最后問題得到了解決,也懂得了原理,遂記錄一下。
他的問題具體是這樣。
1
2
3
4
5
6
|
#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。
首先說一下這個報錯的意思,通俗的說就是,試圖訪問該pointer指向的變量,卻發現該變量是一個不完整的類型,多出錯於訪問結構體聯合體的成員。從代碼中可看出來,是從201行開始才真正的訪問icmp_type指向的變量,200行還沒訪問。
於是我就猜想,是不是struct icmp沒有定義呢?遂粗略的查看了/usr/include/netinet/ip_icmp.h文件,發現有struct icmp的定義。很奇怪,不是嗎?經過寫了一些demo測試,最終的結論是,確實沒有struct icmp的定義!
看到這里,更奇怪了。為什么是這樣的結論呢?細看/usr/include/netinet/ip_icmp.h文件,會發現struct icmp的定義被包含在一個宏里面j,如下面所示:
1
2
3
4
5
6
7
8
9
|
...
#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,,下面總結一下。
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”報錯了
轉自:http://my.oschina.net/michaelyuanyuan/blog/68203?fromerr=quiozj2B