1. 程式人生 > >xilinx zynq SDK 關於編譯報錯“dereferencing pointer to incomplete type

xilinx zynq SDK 關於編譯報錯“dereferencing pointer to incomplete type

    轉自: https://my.oschina.net/michaelyuanyuan/blog/68203

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,如下面所示:

...
#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”報錯了。