2013-10-18 370 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。