Pse*_*che 150 c memset systems-programming
在上一学期的系统编程课程中,我们必须在C中实现一个基本的客户端/服务器.初始化结构,比如sock_addr_in,或者char缓冲区(我们用来在客户端和服务器之间来回发送数据)教授指示我们只使用bzero而不是memset初始化它们.他从未解释过为什么,而且我很好奇是否有正当理由呢?
我在这里看到:http://fdiv.net/2009/01/14/memset-vs-bzero-ultimate-showdown这bzero是更有效的,由于一个只能将要归零记忆的事实,所以也没有必须做任何额外的检查memset.尽管如此,这仍然不一定是绝对不能memset用于归零内存的理由.
bzero被认为已弃用,而且不是标准的C函数.根据手册,memset因此优先考虑bzero.所以,你为什么要仍然使用bzero过memset?只是为了提高效率,还是更多?同样,有什么好处memset了bzero,使它成为新的程序的事实上的首选?
oua*_*uah 144
我看不出有任何理由,更喜欢bzero了memset.
memset是标准的C函数,而bzero从未成为C标准函数.理由可能是因为您可以使用memset函数实现完全相同的功能.
现在关于效率,编译器就像gcc使用内置实现一样,memset当0检测到常量时切换到特定实现.同为glibc当内置命令被禁用.
aus*_*tin 65
我猜你曾经使用过(或者你的老师受到了影响)W.Richard Stevens的UNIX网络编程.即使在最新版本bzero中memset,他也经常使用而不是.这本书如此受欢迎,我认为它已经成为网络编程的成语,这也是你仍然看到它被使用的原因.
我会坚持memset只是因为bzero被弃用并降低了可移植性.我怀疑你会看到使用一个而不是另一个真正的收益.
Mic*_*urr 48
在一个优势,我认为bzero()有超过memset()设定存储到零的是,有一个错误的机会减少正在取得进展.
不止一次,我遇到了一个看起来像的错误:
memset(someobject, size_of_object, 0); // clear object
Run Code Online (Sandbox Code Playgroud)
编译器不会抱怨(虽然可能会在某些编译器上启动某些警告级别),但效果将是内存未被清除.因为这不会破坏对象 - 它只是让它一个人留下 - 这个错误很可能不会显示出任何明显的东西.
bzero()不标准的事实是轻微的刺激.(FWIW,如果我的程序中的大多数函数调用都是非标准的,我不会感到惊讶;事实上,编写这样的函数是我的工作).
在另一个答案的评论中,Aaron Newton引用了以下来自Unix网络编程,第1卷,第3版,Stevens等人,第1.2节(重点补充):
bzero不是ANSI C函数.它源于早期的Berkely网络代码.尽管如此,我们在整个文本中使用它而不是ANSI Cmemset函数,因为bzero它比memset(使用三个参数)更容易记住(只有两个参数).几乎所有支持套接字API的供应商也提供bzero,如果没有,我们在unp.h标头中提供宏定义.事实上,TCPv3 [TCP/IP Illustrated,第3卷 - 史蒂文斯1996]的作者犯了错误,即
memset在第一次打印中将第二和第三个参数交换为10次.AC编译器无法捕获此错误,因为两个参数的类型相同.(实际上,第二个参数是aint和第三个参数size_t,通常是一个unsigned int,但是指定的值,分别为0和16,对于另一种类型的参数仍然可以接受.)调用memset仍然有效,因为只有一个很少有套接字函数实际上要求将Internet套接字地址结构的最后8个字节设置为0.然而,这是一个错误,可以通过使用来避免bzero,因为bzero如果使用函数原型,交换两个参数将始终被C编译器捕获.
我也相信绝大多数调用memset()是零内存,那么为什么不使用针对该用例量身定制的API呢?
可能的缺点bzero()是编译器可能更有可能进行优化,memcpy()因为它是标准的,因此可能会编写它们来识别它.但是,请记住,正确的代码仍然比已经优化的错误代码更好.在大多数情况下,使用bzero()不会对程序的性能产生明显影响,并且bzero()可以是扩展为的宏或内联函数memcpy().
小智 5
随心所欲。:-)
\n\n#ifndef bzero\n#define bzero(d,n) memset((d),0,(n))\n#endif\nRun Code Online (Sandbox Code Playgroud)\n\n注意:
\n\nbzero什么也不返回,memset返回void指针( d)。这可以通过在定义中将类型转换添加到 void 来解决。#ifndef bzero即使原始函数存在,也不会阻止您隐藏它。它测试宏是否存在。这可能会引起很多混乱。bzero通过函数指针使用时,这将不起作用。| 归档时间: |
|
| 查看次数: |
83465 次 |
| 最近记录: |