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

C 如何测试strdup()是否可用?,c,gcc,posix,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(b

我用这个:

#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
#如果!已定义(_SVID_SOURCE)| |!已定义(|BSD|u源)| XOPEN|u源<500||!(_XOPEN_SOURCE&&u XOPEN_SOURCE_EXTENDED)\
||_POSIX_C_源<200809L
字符*strdup(常量字符*s)
{
char*buffer=malloc(strlen+1);
if(缓冲区!=NULL)
strcpy(缓冲区,s);
返回缓冲区;
}
#恩迪夫
但是有可能出现重新声明错误吗?可能是一些gcc版本或类似gcc的编译器?例如,我想使它与没有
strdup()
-ansi
的版本(标准)兼容


另外,如何使其更具可移植性?

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


对于第一个问题,不,您无法确定预处理器是否存在函数。查看此项。

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


对于第一个问题,不,您无法确定预处理器是否存在函数。查看此图。

在我的平台(linux,gnu libc 2.16)上查找
字符串.h
,我发现:

#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
#如果
s稍有不同,我不知道我在标题中找到的那些与您正在使用的那些之间的影响。
关于第二个问题,您可以使用创建描述编译平台功能的
config.h
标题,并使用您自己的缺失函数版本。
此外,您还可以使用“源库”,它提供有缺陷或缺失功能的实现(如)

使用自动工具可以防止任何重新声明错误。

在我的平台(linux,gnu libc 2.16)上查找
字符串.h
,我发现:

#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
#如果
s稍有不同,我不知道我在标题中找到的那些与您正在使用的那些之间的影响。
关于第二个问题,您可以使用创建描述编译平台功能的
config.h
标题,并使用您自己的缺失函数版本。
此外,您还可以使用“源库”,它提供有缺陷或缺失功能的实现(如)

使用自动工具可以防止任何重新声明错误。

这绝对是错误使用功能测试宏。功能测试宏不是由实现定义的,用于告诉应用程序什么是可用的;它们由应用程序定义,以请求实现提供与特定标准(特定版本)的一致性

unistd.h
中,您应该使用宏来测试实现支持什么:

  • \u POSIX\u版本
    -支持POSIX版本<代码>200809L是最新版本
  • \u XOPEN\u VERSION
    -X/Open可移植性指南的版本,现在称为POSIX的“XSI”选项。最新版本是
    700
    (来自SUSv4)<代码>600(SUSv3)是常见的<代码>500(SUSv2)已严重过时
  • \u POSIX_THREADS
    -pthreads的版本(应与
    \u POSIX_version
    相同;自POSIX 2008年起必须提供)

    • 这绝对是对功能测试宏的错误使用。功能测试宏不是由实现定义的,用于告诉应用程序什么是可用的;它们由应用程序定义,以请求实现提供与特定标准(特定版本)的一致性

      unistd.h
      中,您应该使用宏来测试实现支持什么:

      • \u POSIX\u版本
        -支持POSIX版本<代码>200809L是最新版本
      • \u XOPEN\u VERSION
        -X/Open可移植性指南的版本,现在称为POSIX的“XSI”选项。最新版本是
        700
        (来自SUSv4)<代码>600(SUSv3)是常见的<代码>500(SUSv2)已严重过时
      • \u POSIX_THREADS
        -pthreads的版本(应与
        \u POSIX_version
        相同;自POSIX 2008年起必须提供)

      您针对的编译器/环境是什么?这是一个问题?@Jonathan Leffler:对不起。英语不是我的母语;我们是来帮忙的。应该有人回去做更多的工作,但我需要去办公室。请注意,部分问题在于系统库中是否存在
      strdup()
      ;另一部分是系统头中是否声明了
      strdup()
      strdup()
      函数可以存在于系统库中,而无需通过标头声明(可能是因为用户选择了一个配置宏的值太低,例如
      \u XOPEN\u SOURCE
      )。理想情况下,您需要声明和定义。您针对的编译器/环境是什么?这是一个问题?@Jonathan Leffler:对不起。英语不是我的母语;我们是来帮忙的。应该有人回去做更多的工作,但我需要去办公室。请注意,部分问题在于系统库中是否存在
      strdup()
      ;另一部分是系统头中是否声明了
      strdup()
      strdup()
      函数可以存在于系统库中,而无需通过标头声明(可能是因为用户选择了一个配置宏的值太低,例如
      \u XOPEN\u SOURCE
      )。理想情况下,您需要声明和定义。