bzero()
相对于 memset()
来说,唯一的优势在于它减少了出错的可能性。
我曾经遇到过类似这样的错误:
memset(someobject, size_of_object, 0); // clear object
编译器不会报错(虽然在某些编译器上增加一些警告级别可能会),因此内存不会被清除。由于这并没有破坏物体 - 它只是让它保持原样 - 所以有很大的机会,这个错误可能不会表现出明显的问题。
bzero()不是标准函数,这是一个小烦恼。(顺便说一下,我不会惊讶如果我的程序中大部分函数调用都是非标准的;事实上编写这些函数是我的工作之一)。
在回答中的另一个评论中,Aaron Newton引用了Unix Network Programming, Volume 1, 3rd Edition by Stevens, et al.,Section 1.2中的以下内容(重点加粗):
“
bzero不是ANSI C函数。它来源于早期的Berkely网络代码。尽管如此,我们在整个文本中使用它,而不是ANSI C
memset函数,因为
bzero更容易记住(只有两个参数),而
memset有三个参数。几乎每个支持套接字API的供应商也提供
bzero,如果没有,我们在我们的
unp.h头文件中提供宏定义”。
“事实上,《TCPv3》 [TCP/IP Illustrated, Volume 3 - Stevens 1996] 的作者在第一版中的10个地方错误地交换了
memset的第二个和第三个参数。 C编译器无法捕获此错误,因为两个参数类型相同(实际上,第二个参数是int,而第三个参数是size_t,通常是unsigned int,但指定的值0和16仍然接受为其他类型的参数)。调用
memset仍然可以工作,因为只有少数套接字函数需要将Internet套接字地址结构的最后8个字节设置为0。尽管如此,这是一个错误,可以通过使用
bzero来避免,因为如果使用函数原型,交换两个参数到
bzero始终会被C编译器捕获。”
我认为大多数对
memset()的调用都是为了将内存清零,那么为什么不使用专门针对该用例的API呢?
bzero()可能存在的缺点是编译器更可能优化
memcpy(),因为它是标准的,所以它们可能被写成识别它。但请记住,正确的代码仍然比经过优化的不正确的代码要好。在大多数情况下,使用
bzero()不会对程序性能造成明显影响,并且
bzero()可以是一个宏或内联函数,它扩展为
memcpy()。
memset
函数因为 "有一些额外的检查" 可能会稍微不那么高效这一想法视为过早优化是正确的:无论您省略一个或两个 CPU 指令可能获得多少性能提升,在危及代码可移植性的情况下都不值得。bzero
已经过时,这已足够理由不使用它。 - Sergey Kalinichenko= {0}
而无需调用任何函数。当 C 语言在本世纪初停止要求提前声明局部变量时,这变得更加容易。尽管如此,有些真正陈旧的纸质文献仍然停留在上个世纪深处。 - MSalters