我最近成为意识到strdup()
我已经使用了这么多的OS X享受函数不是ANSI C的一部分,但POSIX的一部分。 我不想重写我的所有代码,所以我想我只是写我自己strdup()
函数。 这并不难,真的,这只是一个malloc()
和strcpy()
无论如何,我有作用,但如果我写这篇文章的功能,并将其链接到我的代码,我在做什么,而且它已经在libc的存在? 请问我的连接器或编译器允许我基本上定义我自己的版本功能,还是我给它一个名字吗? 这将是非常方便的,如果有重复使用相同的名称,因此,如果一个方法strcpy()
在用户的libc的存在,他们可以使用,但如果它没有在他们的libc的存在,他们可以使用我的版本代替,用尽可能少的代码改变成为可能。
简短的版本:
一)当我写我自己的函数具有相同的名称作为一个内置的功能,会发生什么?
B)我能做些什么,以避免不好的事情发生在我身上就没有平台strdup()
而无需重写我的代码不使用strdup()
它只是有点乏味?
通常情况下,您只需使用一个#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)
正如罗布·肯尼迪指出,最好的办法就是你的建筑物里面的脚本测试如果这个功能的存在与否。 我知道这是很容易与自动配置,但可能与其它跨平台的建设脚本工具,太。
然后你只需将你的头文件:
#ifndef HAVE_STRDUP
# ifdef HAVE__STRDUP
# define strdup _strdup
# else
# define strdup my_strdup
# endif
#endif
如果的strdup在目标平台上已经存在的libc的版本使用,如果没有你的自定义功能my_strdup将使用。
编辑:我应该补充一个explination为什么它是更好的。
首先编译器是无关的libc中的函数的存在。 例如采取功能strlcpy
。 它存在于FreeBSD的,但不是在Linux(glibc的),虽然两者都使用gcc默认。 或者会发生什么,如果有人会铿锵编译代码?
其次,如果你明确地添加对每个plattform要支持正确的预处理器条件平台检查(我不知道是否有一个标准的方式)才有效。 因此,假如你已经掌握编译您在OSX和Win32应用程序,现在要编译它在Linux上,你必须通过所有预处理条件,看看他们为Linux工作。 也许你也想支持的FreeBSD,OpenBSD的,等等? 再同样的工作。 随着建筑物脚本的测试,它可以编译没有任何额外的工作。
一)当我写我自己的函数具有相同的名称作为一个内置的功能,会发生什么?
你不能重新定义已经存在于你包含一个头文件的功能。 这将导致编译错误。
B)我能做些什么,以避免不好的事情发生在我身上就没有的strdup()而无需重写我的代码不使用的strdup(),它只是有点乏味平台?
我会建议创建自己的包装功能的strdup,并更换所有通话使用新的包装函数。 例如:
char *StringDuplicate(const char *s1)
{
#ifdef POSIX
return strdup(s1);
#else
/* Insert your own code here */
#endif
}
从变化的strdup到StringDuplicate()所有电话应该是一个简单的查找和替换操作,使其成为一个可行的办法。 然后,特定于平台的逻辑将被保存在一个位置,而不是分散在整个代码库。
还应该考虑避免任何标识符(包括功能)的,与海峡[AZ]开始的创建。 虽然这是不保留,C标准(ISO / IEC 9899:1999)第11年7月26日(未来图书馆方向)指出:“随着海峡,MEM,或WCS和小写字母开头可能被添加到声明函数名称在标题“。
FYI:我从来没有亲眼见过那个没有定义的strdup()的环境。
如果任何人读取:不要使用平台的的strdup(),即使使用,也不要浪费在了autoconf / automake的时间/精力只是使用它。 严重的是,如何努力,这就是:
char* mystrdup(const char* str)
{
return strcpy(malloc( strlen(str) + 1),str);
}
这是否真的值得的#ifdefs? 编译器检查? 吻