1

私はこれを使用しています:

#if !defined(_SVID_SOURCE) || !defined(_BSD_SOURCE) || _XOPEN_SOURCE < 500 || !(_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) \
|| _POSIX_C_SOURCE < 200809L
char * strdup(const char *s)
{
  char *buffer = malloc(strlen(s) + 1);

  if(buffer != NULL)
    strcpy(buffer, s);

  return buffer;
}
#endif

しかし、再宣言エラーが発生する可能性はありますか?たぶん、いくつかのgccバージョンまたはgccのようなコンパイラに?たとえば、strdup()がないバージョン(標準)と互換性を持たせたい。-ansi

また、どうすればもっとポータブルにすることができますか?

4

3 に答える 3

2

これは、機能テストマクロの絶対に間違った使用法です。機能テストマクロは、アプリケーションに何が利用可能かを伝えるために実装によって定義されていません。それらは、実装が特定の標準(の特定のバージョン)への適合を提供することを要求するためにアプリケーションによって定義されます。

実装がサポートするものをテストするために使用する必要のあるマクロは次のunistd.hとおりです。

  • _POSIX_VERSION-サポートされているPOSIXのバージョン。200809L最新です。
  • _XOPEN_VERSION--X / Open Portability Guideのバージョン。現在、POSIXの「XSI」オプションと呼ばれています。最新は700(SUSv4から)です。600(SUSv3)が一般的です。500(SUSv2)はひどく時代遅れです。
  • _POSIX_THREADS-pthreadのバージョン(_POSIX_VERSIONPOSIX 2008以降は必須;と同じである必要があります)
  • ..。
于 2012-09-28T18:12:29.543 に答える
1

はい、すでに定義されている場合は、strdupで再宣言されます。このタイプの問題を回避するために私が知っている唯一の方法は、strdupを他の何か(たとえば_strdup)にマクロ化してから、その別の名前でstrdupを定義することです。これは少し醜いですが、それは仕事を成し遂げます。

最初の質問ですが、プリプロセッサに関数が存在するかどうかを判断することはできません。この投稿を参照してください。

于 2012-09-28T16:09:26.700 に答える
1

string.h私のプラットフォーム(linux、gnu libc 2.16)を見ると、次のことがわかりました。

#if defined __USE_SVID || defined __USE_BSD || defined __USE_XOPEN_EXTENDED \
    || defined __USE_XOPEN2K8
/* Duplicate S, returning an identical malloc'd string.  */
extern char *strdup (const char *__s)
     __THROW __attribute_malloc__ __nonnull ((1));
#endif

#if少し異なります。ヘッダーで見つけたものと使用しているものの影響はわかりません。
2番目の質問については、autotoolsconfig.hを使用して、コンパイルプラットフォームの機能を説明するヘッダーを作成し、不足している関数の独自のバージョンを使用できます。
さらに、gnulibの「ソースライブラリ」を使用して、欠陥のある関数や欠落している関数の実装を提供することもできます(などstrdup
。autotoolsを使用すると、再宣言エラーを防ぐことができます。

于 2012-09-28T16:32:51.313 に答える