bzero()和bcopy()与memset()和memcpy()的区别

42

在Linux环境下,是否有使用非标准的bzero()bcopy()而不是memset()memcpy()的原因?我听说很多人说它们更适合Linux编译器,但没有看到与标准函数相比的优势。

它们是否比标准函数更优化,或者它们是否具有任何行为特性,使它们更受欢迎?


5
在所有情况下,memsetbzero更好用,但有一个例外:在某些体系结构中,每个函数参数都需要占用一个栈空间时,你可以使用尾调用从一个仅接受2个参数的函数跳转到bzero函数。至于bcopy函数,我认为它类似于memmove而不是memcpy - R.. GitHub STOP HELPING ICE
2
bcmp(),bcopy(),bzero(),ffs()不建议在重视可移植性的新应用程序中使用,它们仅为了支持BSD应用程序的可移植性而提供。 - Grijesh Chauhan
@Grijesh 我知道他们做什么,我想知道是否有更深层次的特殊之处。 - Iosif Murariu
3个回答

61

虽然 bzerobcopy 函数并不是 ISO C(我认为你在称它们为非标准时,指的是实际标准),但它们确实是 POSIX 标准的一部分,尽管它们早于 ISO 和 POSIX。

请注意使用了"were"这个词 - 这些函数已经在 POSIX.1-2001 中被弃用,最终在 POSIX.1-2008 中被移除,以支持使用 memset, memcpymemmove。因此,在可能的情况下最好使用标准 C 函数。

如果你有很多代码使用它们,而且你不想去改变所有的代码(虽然你应该在某个时候),你可以使用以下快速替换:

// void bzero(void *s, size_t n);
#define bzero(s, n) memset((s), 0, (n))

// void bcopy(const void *s1, void *s2, size_t n);
#define bcopy(s1, s2, n) memmove((s2), (s1), (n))

4
#include <strings.h>
void bcopy(const void *src, void *dest, size_t n);
描述 bcopy()函数从src拷贝n个字节到dest。即使两个区域重叠,结果也是正确的。
符合标准: 4.3BSD,似乎b来自BSD,看起来已被弃用。
这意味着bcopy类似于memmove()而不是memcpy(),正如R..在他的评论中所说。
注意:strings.hstring.h也不同。

7
BSD并不是为了宣传自己的起源而在东西上加上“b”前缀。实际上,“b”似乎代表“字节”。这些函数被描述为在“字节字符串”(与以空字符结尾的文本字符串相对)上操作,可以在这个旧的手册页面中找到:http://www.tuhs.org/cgi-bin/utree.pl?file=4.1cBSD/usr/man/man3/bstring.3 - user2404501

3
现在情况可能正好相反。因为标准中包含了memcpymemset,所以编译器可以假定调用这些函数时会按照标准的要求执行。这意味着编译器可以用最有效的方法来执行操作。然而,对于bcopybzero,标准没有规定任何行为,因此编译器不能假定任何东西 - 这意味着编译器需要发出实际的函数调用。
但是,例如GCC如果构建在拥有bcopybzero的操作系统上,则知道它们的存在。

更准确地说,一些编译器(尤其是最近版本的 GCC)可以以“神奇”的方式(符合标准)处理 memcpymemsetmemcmp,例如使用 GCC 的 内建函数,并且可以特别优化它们。 - Basile Starynkevitch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接