Search code examples
cmanpage

Manpage scandir() prototype weirdness


I have a problem with scandir(): The manpage contains this as prototype:

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

Therefore I have this:

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

And here's the call:

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

Finally the compiler says this:

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

Compiler is gcc-4.3.2, my CFLAGS are following:

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

What is the meaning of this warning? The declaration of RubyCompare looks correct for me and besides the warning the code works completely.


Solution

  • Actually, there's no such constraint that you can't pass a pointer to an inline function. The inline keyword serves only as a hint to the compiler to inline calls when it can.

    The problem is that the manpage for scandir() is a little misleading. The prototype in for the 4th parameter is actually int (*cmp)(const void *, const void *).

    Therefore you need to change the code like so:

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

    I'm not actually sure why you're writing this function, though, because you can use the provided alphasort compare function:

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