首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >strdup()函数

strdup()函数
EN

Stack Overflow用户
提问于 2009-01-27 05:14:57
回答 7查看 24.7K关注 0票数 15

我最近意识到,我喜欢在OS上使用的strdup()函数并不是ANSI的一部分,而是POSIX的一部分。我不想重写所有代码,所以我想我只需要编写自己的strdup()函数即可。实际上,这并不难,它只是一个malloc()和一个strcpy()。不管怎样,我有这个函数,但是如果我编写这个函数并将它链接到我的代码,而它已经存在于libc中,我该怎么办呢?我的链接器或编译器是否允许我基本上定义自己版本的函数,或者我必须给它另一个名称?如果有一种方法可以重用相同的名称,这将是非常方便的,这样如果strcpy()存在于用户的libc中,他们就可以使用它,但是如果它不存在于他们的libc中,他们可以使用我的版本,尽可能少的代码更改。

简短的版本如下:

a)当我用与内置函数相同的名称编写自己的函数时会发生什么?

b)我能做些什么来避免在没有strdup()的平台上发生不好的事情,而不是重写我所有的代码来不使用strdup(),这只是有点乏味?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-01-27 05:19:57

通常,在某个编译器下,您只需使用#if来定义您想要的函数。如果内置库没有定义strdup,那么您自己定义它是没有问题的(除非将来他们定义了它,您必须把它拿出来)。

代码语言:javascript
复制
// Only define strdup for platforms that are missing it..
#if COMPILER_XYZ || COMPILER_ABC
char *strdup(const char *)
{
   // ....
}
#endif
票数 20
EN

Stack Overflow用户

发布于 2009-01-27 05:52:27

你可以像这样使用宏,这样你就可以使用旧名称,但链接器将看到一个不同的名称;

代码语言:javascript
复制
char *my_strdup(const char *s) {
    char *p = malloc(strlen(s) + 1);
    if(p) { strcpy(p, s); }
    return p;
}

/* this goes in whatever header defines my_strdup */
char *my_strdup(const char *s);
#define strdup(x) my_strdup(x)
票数 6
EN

Stack Overflow用户

发布于 2009-01-27 08:30:53

正如Rob肯尼迪所指出的,最好的方法是在您的构建脚本中测试此函数是否存在。我知道使用autoconfig相当简单,但可能使用其他跨平台构建脚本工具也是如此。

然后,您只需在头文件中添加:

代码语言:javascript
复制
#ifndef HAVE_STRDUP
# ifdef HAVE__STRDUP
#  define strdup _strdup
# else
#  define strdup my_strdup
# endif
#endif

如果strdup在目标平台上已经存在,则使用libc版本,否则将使用您的自定义my_strdup函数。

编辑:我应该添加一个解释为什么它更好。

首先,编译器与libc中是否存在函数无关。例如,以函数strlcpy为例。它出现在FreeBSD上,但没有出现在Linux (glibc)上,尽管两个系统默认使用的都是gcc。或者,如果有人要用clang编译你的代码,会发生什么?

其次,平台检查(我不知道是否有标准的方法)只有在您显式地为每个您想要支持正确的预处理器条件的平台添加时才会起作用。因此,假设您已经掌握了在OSX和Win32上编译应用程序的技能,并且现在想要在Linux上编译它,那么您必须检查所有的预处理器条件,看看它们是否适用于Linux。也许您还想支持FreeBSD、OpenBSD等?同样的工作。在您的构建脚本中进行测试后,无需任何额外工作即可进行编译。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/482375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档