2013-10-08 63 views
2

我有以下代碼在unix中打印目錄列表。打印目錄列表時出現奇怪的指針警告

struct dirent *res; 
struct DIR *dir; 
scanf("%s",str); 
dir=opendir(str); 
if(dir==NULL) 
{ 
    perror("Invalid directory"); 
    return 1; 
} 
res=(struct dirent *)readdir(dir); 
while(res) 
{ 
    printf("%s\n",res->d_name); 
    res=(struct dirent *)readdir(dir); 
} 

當我編譯上面的代碼,我得到以下警告

ls.c:16:17: warning: passing argument 1 of ‘readdir’ from incompatible pointer type 
     [enabled by default] 
/usr/include/dirent.h:164:23: note: expected ‘struct DIR *’ but argument is of type 
    ‘struct DIR *’ 
ls.c:20:21: warning: passing argument 1 of ‘readdir’ from incompatible pointer type 
    [enabled by default] 
/usr/include/dirent.h:164:23: note: expected ‘struct DIR *’ but argument is of type 
    ‘struct DIR *’ 

時,它說:「期望的參數foo但參數是foo型」是什麼GCC究竟意味着什麼呢?

我也嘗試使用struct DIR dir代替*dir&dir代替dir,但它會導致以下錯誤

ls.c:7:12: error: storage size of ‘dir’ isn’t known 

PS:代碼的輸出是完全OK。

回答

7

DIR是一個宏,一般擴展到struct something,所以你聲明struct struct something *dir。這顯然是一個令人困惑的事情(儘管GCC顯然也很好),導致了一個令人困惑的錯誤信息。解決方案只需聲明DIR *dir,而不需要struct

+0

它工作:)謝謝。 – rjv

+0

順便說一句,我非常感興趣,我查了相關的語法......在C99中,至少,'struct struct foo'是非法的。 – Sneftel

0

Ben對您的問題有正確的解決方案,但這看起來像是gcc報告此錯誤的嚴重問題。

首先,這不是一個宏觀問題。 DIRstruct __DIR的一個typedef(至少這就是它在這裏,我得到相同的錯誤信息)。沒有struct DIR,除了struct DIR *dir;聲明的那個,但gcc似乎在說有另一個類型的名稱。

此示例編譯單元更清楚地說明此問題:

struct foo { 
    int a,b,c; 
}; 

typedef struct foo bar; 

void do_bar(bar *); 

void func(void) 
{ 
    int i = 0; 

    /* do_bar wants a bar *, which is a struct foo *, but we're giving it an 
    int * instead. What will gcc say? */ 
    do_bar(&i); 
} 

GCC報道:

t.c: In function ‘func’: 
t.c:15:7: warning: passing argument 1 of ‘do_bar’ from incompatible pointer type [enabled by default] 
t.c:7:10: note: expected ‘struct bar *’ but argument is of type ‘int *’ 

但在代碼中沒有struct bar可言。它已經採取了bar typedef並且在它前面塞滿了字struct