2013-10-18 372 views
2

我试图用scandir打印当前目录中的文件列表。当我尝试编译,我收到以下错误和警告:scandir的隐式声明; alphasort未声明

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标志进行编译。

我可以简单地忽略一些东西吗?我无法弄清楚为什么它不能编译。

+1

不同消息的原因是编译器从上下文知道'scandir()'必须是一个函数,但从上下文无法判断'alphasort()'是一个函数。 –

回答

4

如果使用-std=c99,只头文件包含严格属于C99标准一部分的函数。 scandir()不在C99标准中。因此,您必须设置预处理器变量以确保包含函数原型。例如,scandir()的手册页指示在执行#include之前设置_BSD_SOURCE_SVID_SOURCE预处理器变量将解决该问题。或者,您可以使用#define _GNU_SOURCE,这将依次为您设置不同的变量(包括_BSD_SOURCE_SVID_SOURCE)。

由于C允许您使用隐式定义的函数进行编译,并且链接器将正确地将该调用连接到scandir()以正确的函数,所以您的代码仍然会在编译时显示警告和工作。

+0

谢谢,添加'#define _GNU_SOURCE'解决了我的问题。 – Bluedanes

+1

这些函数也在POSIX中,所以'#define _XOPEN_SOURCE 700'也能很好地工作。 –

0

尝试#include <sys/dir.h>文件使用SCANDIR和定义extern int alphasort(const void*,const void*);extern int alphasort();以上的printFiles

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

+0

我忽略了一些包含内容,但我使用了'''''和其他一些内容。还有其他几种与其他特定功能有关的其他功能。 我也尝试把你建议的定义,他们没有改变任何东西。有任何想法吗? – Bluedanes

+0

@Bluedanes检查sys/dir.h是否在此处声明alphasort? –

+0

'sys/dir.h'不在MinGW中。 –

1

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

  1. 发现SCANDIR,你会发现这使得SCANDIR Invisible.for例如在我的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 
    

    你知道现在要做什么?不要担心!它不是一个直接定义这个宏的好方法。

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

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

    它告诉,如果“_BSD_SOURCE ”或“ _SVID_SOURCE“被定义,那么__USE_MISC将被定义为auto。

  3. 考虑兼容性的你自己的代码,在开始添加语句如下(任一方或双方)(任何语句之前一样的#include < .H> ||“ .H”)的文件,你将使用SCANDIR ()。

    #define _BSD_SOURCE 1 
    #define _SVID_SOURCE 1 
    
  4. 保存您的文件和make。