如何测试strdup()是否可用?

时间:2012-09-28 16:04:30

标签: c gcc posix

我正在使用它:

#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的版本(标准)兼容。

另外,我怎样才能让它更便携?

3 个答案:

答案 0 :(得分:2)

这绝对是功能测试宏的错误使用。实现没有定义功能测试宏来告诉应用程序可用的内容;它们由应用程序定义,要求实现提供与特定标准(特定版本)的一致性。

您应该使用的宏来测试实现支持的内容unistd.h

  • _POSIX_VERSION - 支持POSIX版本。 200809L是最新的。
  • _XOPEN_VERSION - X / Open Portability Guide的版本,现在称为POSIX的“XSI”选项。最新的是700(来自SUSv4)。 600(SUSv3)很常见。 500(SUSv2)严重过时。
  • _POSIX_THREADS - pthreads的版本(应与_POSIX_VERSION相同;自POSIX 2008起必须使用)
  • ...

答案 1 :(得分:1)

是的,如果它已经定义,您将在strdup上重新声明。我知道解决这类问题的唯一方法是宏strdup到其他东西(比如_strdup),然后用另一个名字定义strdup。这有点难看,但它完成了工作。

对于您的第一个问题,您无法确定预处理器是否存在函数。请参阅此post

答案 2 :(得分: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略有不同,我不知道我在标题中找到的与您正在使用的标题之间的影响。
关于第二个问题,您可以使用autotools创建一个描述编译平台功能的config.h标题,并使用您自己的缺失函数版本。
此外,您还可以使用gnulib&#34;源库&#34;它提供有缺陷或缺失功能的实现(如strdup
使用自动工具应该可以防止任何重新声明错误。