6

我对scandir()有疑问:联机帮助页包含此作为原型:

int scandir(const char *dir, struct dirent ***namelist,
  int (*filter)(const struct dirent *),
  int (*compar)(const struct dirent **, const struct dirent **));

因此我有这个:

static inline int
RubyCompare(const struct dirent **a,
  const struct dirent **b)
{
  return(strcmp((*a)->d_name, (*b)->d_name));
}

这是电话:

num = scandir(buf, &entries, NULL, RubyCompare);

最后编译器这样说:

warning: passing argument 4 of ‘scandir’ from incompatible pointer type

编译器是gcc-4.3.2,我的 CFLAGS 如下:

-Wall -Wpointer-arith -Wstrict-prototypes -Wunused -Wshadow -std=gnu99

这个警告的含义是什么?RubyCompare 的声明对我来说看起来是正确的,除了警告之外,代码完全可以工作。

4

3 回答 3

5

实际上,不存在不能将指针传递给内联函数的约束。inline 关键字仅用作提示编译器在可能的情况下内联调用。

问题是 scandir() 的手册页有点误导。第 4 个参数的原型实际上是 int (*cmp)(const void *, const void *)。

因此,您需要像这样更改代码:

static inline int RubyCompare(const void *a, const void *b)
{
    return(strcmp((*(struct dirent **)a)->d_name, 
                  (*(struct dirent **)b)->d_name));
}

不过,我实际上不确定您为什么要编写此函数,因为您可以使用提供的 alphasort 比较函数:

num = scandir(buf, &entries, NULL, alphasort);
于 2008-09-28T17:55:23.560 回答
3

这个原型在最近版本的 GNU libc 中实际上已经改变以反映 POSIX 标准。

如果您有要同时处理旧代码和新代码的代码,请使用 __GLIBC_PREREQ 宏,例如

#define USE_SCANDIR_VOIDPTR 
#if defined( __GLIBC_PREREQ  )
# if  __GLIBC_PREREQ(2,10)
#  undef USE_SCANDIR_VOIDPTR
# endif
#endif

#ifdef USE_SCANDIR_VOIDPTR
 static int RubyCompare(const void *a,  const void *b)
#else 
 static int RubyCompare(const struct dirent **a,  const struct dirent **b)
#endif

...

于 2009-09-14T21:48:46.867 回答
1

你给它一个指向内联函数的指针?这没有意义,实际上我想知道它甚至只编译一个警告。

编辑:上面的克里斯是对的,当 inline 关键字没有意义/不适用时,它会被默默地忽略。

于 2008-09-28T17:32:08.810 回答