打印目录列表时出现奇怪的指针警告

时间:2013-10-08 13:43:44

标签: c

我有以下代码在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 *’

GCC在说出“预期参数foo但参数类型为foo”时的确切含义是什么?

我还尝试使用struct DIR dir代替*dir&dir代替dir,但会导致以下错误

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

PS:代码输出完全正常。

2 个答案:

答案 0 :(得分:7)

DIR是一个宏,通常会扩展为struct something,因此您声明struct struct something *dir。这显然是一件令人困惑的事情(尽管GCC也显然很好),导致一个令人困惑的错误信息。解决方案只是声明DIR *dir,而不是struct

答案 1 :(得分: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这个词。