2008-09-28 49 views
5

我有SCANDIR(有問題):該手冊頁包含此爲原型:聯機幫助SCANDIR()的原型古怪

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

所以我有這樣的:

static inline int 
RubyCompare(const struct dirent **a, 
    const struct dirent **b) 
{ 
    return(strcmp((*a)->d_name, (*b)->d_name)); 
} 

而這裏的呼叫:

num = scandir(buf, &entries, NULL, RubyCompare); 

最後編譯器說這個:

warning: passing argument 4 of ‘scandir’ from incompatible pointer type 

編譯器是GCC-4.3.2,我的CFLAGS是以下幾點:

-Wall -Wpointer-arith -Wstrict-prototypes -Wunused -Wshadow -std=gnu99 

這是什麼警告的含義是什麼? RubyCompare的聲明對我來說看起來是正確的,並且警告代碼完全工作。

回答

5

實際上,沒有這樣的限制,您無法將指針傳遞給內聯函數。 inline關鍵字僅用於提示編譯器在可能的情況下內聯調用。

問題是,scandir()的manpage有點誤導。第四個參數的原型實際上是int(* cmp)(const void *,const void *)。

因此,你需要改變,像這樣的代碼:

static inline int RubyCompare(const void *a, const void *b) 
{ 
    return(strcmp((*(struct dirent **)a)->d_name, 
        (*(struct dirent **)b)->d_name)); 
} 

我實際上並不知道爲什麼你寫的這個功能,不過,因爲你可以使用提供alphasort比較功能:

num = scandir(buf, &entries, NULL, alphasort); 
+0

好吧好吧,我寫我自己的版本,因爲manpage對alphasort()的可移植性也有誤導作用。用alphasort()它的作品,很有趣,我從來沒有嘗試過。 ;) – unexist 2008-09-28 18:18:23

+0

這樣做會給我一個警告,因爲它拋棄了void參數中的const限定符。有沒有解決的辦法? – TartanLlama 2011-04-21 12:37:30

1

你給它一個指向內聯函數的指針嗎?這沒有意義,實際上我不知道它甚至只是編寫了一個警告。

編輯:上面的Chris是正確的,inline關鍵字在沒有意義/不適用時被默默地忽略。

3

這個原型實際上在GNU libc的最新版本中已經發生了變化,以反映POSIX標準。

如果要在新,舊代碼工作代碼,然後用__GLIBC_PREREQ宏像

#define USE_SCANDIR_VOIDPTR 
#if defined(__GLIBC_PREREQ ) 
# if __GLIBC_PREREQ(2,10) 
# undef USE_SCANDIR_VOIDPTR 
# endif 
#endif 

#ifdef USE_SCANDIR_VOIDPTR 
static int RubyCompare(const void *a, const void *b) 
#else 
static int RubyCompare(const struct dirent **a, const struct dirent **b) 
#endif 

...