问题
I am trying to use scandir
to print a list of files in the current directory. When I try to compile, I am receiving the following errors and warnings:
warning: implicit declaration of function ‘scandir’ [-Wimplicit-function-declaration]
error: ‘alphasort’ undeclared (first use in this function)
note: each undeclared identifier is reported only once for each function it appears in
I am including <dirent.h>
, which to my knowledge should define scandir()
and all related functions. And I don't see any errors in my code:
#include <dirent.h>
...
int printFiles(){
struct dirent **nameList;
int numOfFiles = scandir(".", &nameList, 0, alphasort);
//TODO print file names
return numOfFiles;
}
....
I am running Ubuntu 12.04, and I'm compiling using gcc
with the -c99
flag.
Am I simply overlooking something? I can't figure out why it's failing to compile.
回答1:
If you use -std=c99
, only functions that are strictly a part of the C99 standard are included by the header files. scandir()
is not in the C99 standard. Therefore, you have to set a preprocessor variable to ensure that the function prototype is included. For example, the man page for scandir()
indicates that setting the _BSD_SOURCE
or _SVID_SOURCE
preprocessor variables before you do the #include
will fix the problem. Or, you can use #define _GNU_SOURCE
which will in turn set quite a few different variables for you (including _BSD_SOURCE
and _SVID_SOURCE
).
Your code will still compile with the warning and work because C allows you to compile with implicitly defined functions, and the linker will correctly link the call to scandir()
to the proper function.
回答2:
what macro you use is decided by the macro in dirent.h on your own computer.usually it located in /usr/include/dirent.h.
find scandir in dirent.h ,you will find the macro which make scandir Invisible.for example in my conmputer,it is "__USE_BSD ,__USE_MISC".
#if defined __USE_BSD || defined __USE_MISC /* Return the file descriptor used by DIRP. */ extern int dirfd (DIR *__dirp) __THROW __nonnull ((1)); # if defined __OPTIMIZE__ && defined _DIR_dirfd # define dirfd(dirp) _DIR_dirfd (dirp) # endif # ifndef MAXNAMLEN /* Get the definitions of the POSIX.1 limits. */ # include <bits/posix1_lim.h> /* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'. */ # ifdef NAME_MAX # define MAXNAMLEN NAME_MAX # else # define MAXNAMLEN 255 # endif # endif # define __need_size_t # include <stddef.h> # ifndef __USE_FILE_OFFSET64 extern int scandir (__const char *__restrict __dir, struct dirent ***__restrict __namelist, int (*__selector) (__const struct dirent *), int (*__cmp) (__const void *, __const void *)) __nonnull ((1, 2)); # else # ifdef __REDIRECT extern int __REDIRECT (scandir, (__const char *__restrict __dir, struct dirent ***__restrict __namelist, int (*__selector) (__const struct dirent *), int (*__cmp) (__const void *, __const void *)), scandir64) __nonnull ((1, 2)); # else # define scandir scandir64 # endif # endif
you know what to do now? don't be worry!it not a nice way to #define this macro directly.
open file features.h(located /usr/include/features.h),search "__USE_MISC" inside,you can see codes below:
#if defined _BSD_SOURCE || defined _SVID_SOURCE # define __USE_MISC 1 #endif
it tells that if"_BSD_SOURCE "or"_SVID_SOURCE"is defined,then __USE_MISC would be defined auto.
consider Compatibility of you own codes,add statement below(any one or both) at start(before any statement like #include <.h>||".h") of you file which will use scandir().
#define _BSD_SOURCE 1 #define _SVID_SOURCE 1
save your file and make.
回答3:
try to #include <sys/dir.h>
file to use scandir and define extern int alphasort(const void*,const void*);
or extern int alphasort();
above your printFiles
also - you should link you program with standard library (hope it is already done)
来源:https://stackoverflow.com/questions/19439855/implicit-declaration-of-scandir-alphasort-is-undeclared