隐含的scandir声明; alphasort未声明

时间:2013-10-18 00:57:24

标签: c c99 scandir

我正在尝试使用scandir打印当前目录中的文件列表。当我尝试编译时,我收到以下错误和警告:

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

我包括<dirent.h>,据我所知,应该定义scandir()和所有相关功能。我的代码中没有看到任何错误:

#include <dirent.h>
...
int printFiles(){
    struct dirent **nameList;
    int numOfFiles = scandir(".", &nameList, 0, alphasort);

    //TODO print file names
    return numOfFiles;
}
....

我正在运行Ubuntu 12.04,我正在使用gcc标记使用-c99进行编译。

我只是忽略了什么?我无法弄清楚为什么它无法编译。

3 个答案:

答案 0 :(得分:4)

如果使用-std=c99,则头文件中仅包含严格属于C99标准的功能。 scandir()不符合C99标准。因此,您必须设置预处理器变量以确保包含函数原型。例如,scandir()的手册页表示在执行_BSD_SOURCE之前设置_SVID_SOURCE#include预处理器变量将解决问题。或者,您可以使用#define _GNU_SOURCE来为您设置相当多的不同变量(包括_BSD_SOURCE_SVID_SOURCE)。

您的代码仍将使用警告编译并正常工作,因为C允许您使用隐式定义的函数进行编译,并且链接器将正确地将对scandir()的调用链接到正确的函数。

答案 1 :(得分:1)

您使用的宏由您自己计算机上的dirent.h中的宏决定。它位于/usr/include/dirent.h中。

  1. 在dirent.h中找到scandir,你会发现制作scandir Invisible的宏。例如在我的conmputer中,它是“__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
    
    你知道现在该怎么办吗?别担心!这不是直接#define这个宏的好方法。

  2. 打开文件features.h(位于/usr/include/features.h),搜索“__USE_MISC”里面,你可以看到下面的代码:

    #if defined _BSD_SOURCE || defined _SVID_SOURCE
    # define __USE_MISC 1
    #endif
    

    它告诉我们如果定义了“_BSD_SOURCE”或“_SVID_SOURCE”,那么__USE_MISC将被自动定义。

  3. 考虑您自己的代码的兼容性,在开始时添加下面的语句(任何一个或两个)(在任何语句之前,如#include&lt; .h&gt; ||“ .h”)您将使用scandir()的文件。

    #define _BSD_SOURCE  1
    #define _SVID_SOURCE 1
    
  4. 保存您的文件并制作。

答案 2 :(得分:0)

尝试#include <sys/dir.h>文件使用scandir并在extern int alphasort(const void*,const void*);

上方定义extern int alphasort();printFiles

也 - 你应该把你的程序与标准库联系起来(希望它已经完成)