6

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 の宣言は私には正しいように見え、警告以外にコードは完全に機能します。

4

3 に答える 3

5

実際には、インライン関数にポインターを渡すことができないという制約はありません。inline キーワードは、可能な場合に呼び出しをインライン化するためのコンパイラへのヒントとしてのみ機能します。

問題は、scandir() のマンページが少し誤解を招くことです。4 番目のパラメーターのプロトタイプは、実際には 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);
于 2008-09-28T17:55:23.560 に答える
3

このプロトタイプは、POSIX標準を反映するために、最近のバージョンのGNUlibcで実際に変更されています。

古いコードと新しいコードの両方で作業したいコードがある場合は、__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

..。

于 2009-09-14T21:48:46.867 に答える
1

インライン関数へのポインタを与えていますか? それは意味がありません。実際には、警告だけでコンパイルされるのだろうかと思います。

編集:上記のクリスは正しいです。インラインキーワードは、意味をなさない/適用できない場合、黙って無視されます。

于 2008-09-28T17:32:08.810 に答える