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 *’

当 GCC 说“预期的参数foo但参数是类型foo”时,它到底是什么意思?

我也尝试过使用struct DIR dir而不是*dir&dir而不是dir,但它会导致以下错误

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

PS:代码的输出是完全OK的。

4

2 回答 2

8

DIR 是一个通常扩展为 的宏struct something,因此您要声明struct struct something *dir. 这显然是一件令人困惑的事情(尽管 GCC 显然也很好),导致了令人困惑的错误消息。解决方案是简单地声明DIR *dir,没有struct.

于 2013-10-08T13:47:29.037 回答
0

Ben 对您的问题有正确的解决方案,但这看起来确实是 gcc 如何报告此错误的一个严重问题。

首先,这不是一个宏观问题。DIR是一个 typedef struct __DIR(至少这里是这样,我得到相同的错误消息)。除了由gccstruct DIR声明的那个之外,没有其他类型。struct DIR *dir;

这个示例编译单元更清楚地展示了这个问题:

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代码中根本没有。它采用了bartypedef 并将这个词struct无缘无故地塞在了它的前面。

于 2013-10-08T14:07:16.130 回答