standards/142255: scandir prototype in dirent.h isn't compliant with POSIX 2008

Kevin Barry ta0kira at
Sun Jan 3 01:10:02 UTC 2010

>Number:         142255
>Category:       standards
>Synopsis:       scandir prototype in dirent.h isn't compliant with POSIX 2008
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-standards
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jan 03 01:10:01 UTC 2010
>Originator:     Kevin Barry
>Release:        8.0-RELEASE
FreeBSD 8.0-RELEASE FreeBSD 8.0-RELEASE #0: Sat Nov 21 15:02:08 UTC 2009     root at  amd64
The POSIX standard declares 'scandir' as follows, copied directly:

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

The problem in FreeBSD is the 'sel' argument, which is a pointer to a function taking a 'struct dirent *' without the 'const'. This is a problem when trying to write POSIX-portable code. In C I only receive a warning when trying to pass a function pointer of the correct type, however, in C++ this is an error. An argument cast isn't the solution because I still need my code to work in Linux; therefore, I've had to separate the call to 'scandir' in a C file, separate from the C++ code. Another solution is to C-cast a pointer to 'scandir' and dereference it, which I might consider. Thanks!
Kevin Barry
#include <dirent.h>

static int sel(const struct dirent*)
{ return 1; }

int main()
{ scandir(0, 0, &sel, 0); }

Compile the above with g++.
Change the prototype of 'scandir' in dirent.h.


More information about the freebsd-standards mailing list