The one advantage that I think bzero()
has over memset()
for setting memory to zero is that there's a reduced chance of a mistake being made.
More than once I've come across a bug that looked like:
memset(someobject, size_of_object, 0); // clear object
The compiler won't complain (though maybe cranking up some warning levels might on some compilers) and the effect will be that the memory isn't cleared. Because this doesn't trash the object - it just leaves it alone - there's a decent chance that the bug might not manifest into anything obvious.
The fact that bzero()
isn't standard is a minor irritant. (FWIW, I wouldn't be surprised if most function calls in my programs are non-standard; in fact writing such functions is kind of my job).
In a comment to another answer here, Aaron Newton cited the following from Unix Network Programming, Volume 1, 3rd Edition by Stevens, et al., Section 1.2 (emphasis added):
bzero
is not an ANSI C function. It is derived from early Berkely
networking code. Nevertheless, we use it throughout the text, instead
of the ANSI C memset
function, because bzero
is easier to remember
(with only two arguments) than memset
(with three arguments). Almost
every vendor that supports the sockets API also provides bzero
, and
if not, we provide a macro definition in our unp.h
header.
Indeed, the author of TCPv3 [TCP/IP Illustrated, Volume 3 - Stevens 1996] made the mistake of swapping the second
and third arguments to memset
in 10 occurrences in the first
printing. A C compiler cannot catch this error because both arguments
are of the same type. (Actually, the second argument is an int
and
the third argument is size_t
, which is typically an unsigned int
,
but the values specified, 0 and 16, respectively, are still acceptable
for the other type of argument.) The call to memset
still worked,
because only a few of the socket functions actually require that the
final 8 bytes of an Internet socket address structure be set to 0.
Nevertheless, it was an error, and one that could be avoided by using
bzero
, because swapping the two arguments to bzero
will always be
caught by the C compiler if function prototypes are used.
I also believe that the vast majority of calls to memset()
are to zero memory, so why not use an API that is tailored to that use case?
A possible drawback to bzero()
is that compilers might be more likely to optimize memcpy()
because it's standard and so they might be written to recognize it. However, keep in mind that correct code is still better than incorrect code that's been optimized. In most cases, using bzero()
will not cause a noticeable impact on your program's performance, and that bzero()
can be a macro or inline function that expands to memcpy()
.
memset
may be slightly less efficient because of "a bit more checking going" is definitely a case of premature optimization: whatever the gains that you might see from omitting a CPU instruction or two are not worth it when you can jeopardize portability of your code.bzero
is obsolete, and that's enough reason not to use it. – Witlingexplicit_bzero
or justbzero
? This distinction matters a lot as far as best practices and general rules about whether you should use it instead ofmemset
go. – Excitability