我最近意识到strdup()
我喜欢在OS X上使用的功能不是ANSI C的一部分,而是POSIX的一部分.我不想重写我的所有代码,所以我想我只是要编写自己的strdup()
函数.这并不难,真的,它只是一个malloc()
和一个strcpy()
.无论如何,我有这个功能,但是如果我编写这个函数并将其链接到我的代码,我该怎么做,它已经存在于libc中了?我的链接器或编译器是否允许我基本上定义我自己的函数版本,还是我必须给它另一个名字?如果有一种方法可以重用相同的名称,那将是非常方便的,因此如果strcpy()
存在于用户的libc中,他们可以使用它,但如果它们的libc中不存在,则可以使用我的版本,而只需使用少量代码尽可能地改变.
简短版本:
a)当我编写与内置函数同名的自己的函数时会发生什么?
b)我可以做些什么来避免在strdup()
没有重写我的所有代码而不使用的平台上发生的不良事情strdup()
,这有点单调乏味?
通常,您只需使用an #if
来定义在某个编译器下所需的函数.如果内置库没有定义strdup,那么自己定义它是没有问题的(除非他们将来定义它,否则你必须把它取出来.)
// Only define strdup for platforms that are missing it.. #if COMPILER_XYZ || COMPILER_ABC char *strdup(const char *) { // .... } #endif
您可以使用这样的宏,这样您可以使用旧名称,但链接器将看到不同的名称;
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)
正如Rob Kennedy所指出的那样,如果这个函数存在与否,那么最好的方法是在你的构建脚本中进行测试.我知道使用autoconfig相当容易,但也可能使用其他跨平台构建脚本工具.
然后,您只需将其放在头文件中:
#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等?同样的工作.通过在您的构建脚本中进行测试,它可以在没有任何额外工作的情