bind.2, mount_setattr.2, openat2.2, perf_event_open.2, pidfd_send_signal.2, recvmmsg.2, seccomp_unotify.2, select_tut.2, sendmmsg.2, set_thread_area.2, sysctl.2, bzero.3, getaddrinfo.3, getaddrinfo_a.3, getutent.3, mbrtowc.3, mbsinit.3, rtime.3, rtnetlink.3, strptime.3, NULL.3const, size_t.3type, void.3type, aio.7, netlink.7, unix.7: Prefer bzero(3) over memset(3)
PATCH 1/1 bind.2, mount_setattr.2, openat2.2, perf_event_open.2, pidfd_send_signal.2, recvmmsg.2, seccomp_unotify.2, select_tut.2, sendmmsg.2, set_thread_area.2, sysctl.2, bzero.3, getaddrinfo.3, getaddrinfo_a.3, getutent.3, mbrtowc.3, mbsinit.3, rtime.3, rtnetlink.3, strptime.3, NULL.3const, size_t.3type, void.3type, aio.7, netlink.7, unix.7: Prefer bzero(3) over memset(3)
bzero(3) is simpler to use, and can avoid silly mistakes that are hard to spot. memset(3), while it is necessary in a few very-specific cases, should be avoided when the memory is to be zeroed.
POSIX and ISO can say otherwise, but it doesn't make any sense to recommend using memset(3) over bzero(3).
--- man2/bind.2 | 2 +- man2/mount_setattr.2 | 4 ++-- man2/openat2.2 | 4 ++-- man2/perf_event_open.2 | 2 +- man2/pidfd_send_signal.2 | 2 +- man2/recvmmsg.2 | 2 +- man2/seccomp_unotify.2 | 2 +- man2/select_tut.2 | 6 +++--- man2/sendmmsg.2 | 6 +++--- man2/set_thread_area.2 | 2 +- man2/sysctl.2 | 2 +- man3/bzero.3 | 4 +--- man3/getaddrinfo.3 | 4 ++-- man3/getaddrinfo_a.3 | 2 +- man3/getutent.3 | 6 +++--- man3/mbrtowc.3 | 2 +- man3/mbsinit.3 | 2 +- man3/rtime.3 | 2 +- man3/rtnetlink.3 | 2 +- man3/strptime.3 | 2 +- man3const/NULL.3const | 2 +- man3type/size_t.3type | 1 + man3type/void.3type | 1 + man7/aio.7 | 2 +- man7/netlink.7 | 4 ++-- man7/unix.7 | 6 +++--- 26 files changed, 38 insertions(+), 38 deletions(-)
man2/bind.2 +1 -1
@@ -243,7 +243,7 @@ .SH EXAMPLES if (sfd == \-1) handle_error("socket"); - memset(&my_addr, 0, sizeof(my_addr)); + bzero(&my_addr, sizeof(my_addr)); my_addr.sun_family = AF_UNIX; strncpy(my_addr.sun_path, MY_SOCK_PATH, sizeof(my_addr.sun_path) \- 1);
man2/mount_setattr.2 +2 -2
@@ -878,13 +878,13 @@ .SS Extensibility .in .PP Alternatively, the structure can be zero-filled using -.BR memset (3) +.BR bzero (3) or similar functions: .PP .in +4n .EX struct mount_attr attr; -memset(&attr, 0, sizeof(attr)); +bzero(&attr, sizeof(attr)); attr.attr_set = MOUNT_ATTR_RDONLY; attr.attr_clr = MOUNT_ATTR_NODEV; .EE
man2/openat2.2 +2 -2
@@ -558,13 +558,13 @@ .SS Extensibility .in .PP or explicitly using -.BR memset (3) +.BR bzero (3) or similar: .PP .in +4n .EX struct open_how how; -memset(&how, 0, sizeof(how)); +bzero(&how, sizeof(how)); how.flags = O_RDWR; how.resolve = RESOLVE_IN_ROOT; .EE
man2/perf_event_open.2 +1 -1
@@ -3761,7 +3761,7 @@ .SH EXAMPLES long long count; struct perf_event_attr pe; - memset(&pe, 0, sizeof(pe)); + bzero(&pe, sizeof(pe)); pe.type = PERF_TYPE_HARDWARE; pe.size = sizeof(pe); pe.config = PERF_COUNT_HW_INSTRUCTIONS;
man2/pidfd_send_signal.2 +1 -1
@@ -213,7 +213,7 @@ .SH EXAMPLES /* Populate a \(aqsiginfo_t\(aq structure for use with pidfd_send_signal(). */ - memset(&info, 0, sizeof(info)); + bzero(&info, sizeof(info)); info.si_code = SI_QUEUE; info.si_signo = sig; info.si_errno = 0;
man2/recvmmsg.2 +1 -1
@@ -244,7 +244,7 @@ .SS Program source exit(EXIT_FAILURE); } - memset(msgs, 0, sizeof(msgs)); + bzero(msgs, sizeof(msgs)); for (size_t i = 0; i < VLEN; i++) { iovecs[i].iov_base = bufs[i]; iovecs[i].iov_len = BUFSIZE;
man2/seccomp_unotify.2 +1 -1
@@ -1838,7 +1838,7 @@ .SS Program source /* Wait for next notification, returning info in \(aq*req\(aq */ - memset(req, 0, sizes.seccomp_notif); + bzero(req, sizes.seccomp_notif); if (ioctl(notifyFd, SECCOMP_IOCTL_NOTIF_RECV, req) == \-1) { if (errno == EINTR) continue;
man2/select_tut.2 +3 -3
@@ -373,7 +373,7 @@ .SH EXAMPLES return \-1; } - memset(&addr, 0, sizeof(addr)); + bzero(&addr, sizeof(addr)); addr.sin_port = htons(listen_port); addr.sin_family = AF_INET; if (bind(lfd, (struct sockaddr *) &addr, sizeof(addr)) == \-1) {
@@ -399,7 +399,7 @@ .SH EXAMPLES return \-1; } - memset(&addr, 0, sizeof(addr)); + bzero(&addr, sizeof(addr)); addr.sin_port = htons(connect_port); addr.sin_family = AF_INET;
@@ -508,7 +508,7 @@ .SH EXAMPLES int fd; addrlen = sizeof(client_addr); - memset(&client_addr, 0, addrlen); + bzero(&client_addr, addrlen); fd = accept(h, (struct sockaddr *) &client_addr, &addrlen); if (fd == \-1) { perror("accept()");
man2/sendmmsg.2 +3 -3
@@ -201,17 +201,17 @@ .SH EXAMPLES exit(EXIT_FAILURE); } - memset(msg1, 0, sizeof(msg1)); + bzero(msg1, sizeof(msg1)); msg1[0].iov_base = "one"; msg1[0].iov_len = 3; msg1[1].iov_base = "two"; msg1[1].iov_len = 3; - memset(&msg2, 0, sizeof(msg2)); + bzero(&msg2, sizeof(msg2)); msg2.iov_base = "three"; msg2.iov_len = 5; - memset(msg, 0, sizeof(msg)); + bzero(msg, sizeof(msg)); msg[0].msg_hdr.msg_iov = msg1; msg[0].msg_hdr.msg_iovlen = 2;
man2/set_thread_area.2 +1 -1
@@ -207,7 +207,7 @@ .SH BUGS if set, would prevent the descriptor from being considered empty (see .BR modify_ldt (2)). As a result, the only reliable way to clear a TLS entry is to use -.BR memset (3) +.BR bzero (3) to zero the entire .I user_desc structure, including padding bits, and then to set the
man2/sysctl.2 +1 -1
@@ -137,7 +137,7 @@ .SH EXAMPLES size_t osnamelth; struct __sysctl_args args; - memset(&args, 0, sizeof(args)); + bzero(&args, sizeof(args)); args.name = name; args.nlen = ARRAY_SIZE(name); args.oldval = osname;
man3/bzero.3 +1 -3
@@ -62,9 +62,7 @@ .SH ATTRIBUTES .SH STANDARDS The .BR bzero () -function is deprecated (marked as LEGACY in POSIX.1-2001); use -.BR memset (3) -in new programs. +function is marked as LEGACY in POSIX.1-2001; POSIX.1-2008 removes the specification of .BR bzero (). The
man3/getaddrinfo.3 +2 -2
@@ -671,7 +671,7 @@ .SS Server program exit(EXIT_FAILURE); } - memset(&hints, 0, sizeof(hints)); + bzero(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
@@ -770,7 +770,7 @@ .SS Client program /* Obtain address(es) matching host/port. */ - memset(&hints, 0, sizeof(hints)); + bzero(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = 0;
man3/getaddrinfo_a.3 +1 -1
@@ -360,7 +360,7 @@ .SS Synchronous example perror("malloc"); exit(EXIT_FAILURE); } - memset(reqs[i], 0, sizeof(*reqs[0])); + bzero(reqs[i], sizeof(*reqs[0])); reqs[i]\->ar_name = argv[i + 1]; }
man3/getutent.3 +3 -3
@@ -317,7 +317,7 @@ .SH EXAMPLES strcpy(entry.ut_id, ttyname(STDIN_FILENO) + strlen("/dev/tty")); time(&entry.ut_time); strcpy(entry.ut_user, getpwuid(getuid())\->pw_name); - memset(entry.ut_host, 0, UT_HOSTSIZE); + bzero(entry.ut_host, UT_HOSTSIZE); entry.ut_addr = 0; setutent(); pututline(&entry);
@@ -325,9 +325,9 @@ .SH EXAMPLES system("echo after adding entry:;who"); entry.ut_type = DEAD_PROCESS; - memset(entry.ut_line, 0, UT_LINESIZE); + bzero(entry.ut_line, UT_LINESIZE); entry.ut_time = 0; - memset(entry.ut_user, 0, UT_NAMESIZE); + bzero(entry.ut_user, UT_NAMESIZE); setutent(); pututline(&entry);
man3/mbrtowc.3 +1 -1
@@ -145,7 +145,7 @@ .SH DESCRIPTION .PP .in +4n .EX -memset(&a, 0, sizeof(a)); +bzero(&a, sizeof(a)); .EE .in .SH RETURN VALUE
man3/mbsinit.3 +1 -1
@@ -58,7 +58,7 @@ .SH DESCRIPTION .in +4n .EX mbstate_t state; -memset(&state, 0, sizeof(state)); +bzero(&state, sizeof(state)); .EE .in .PP
man3/rtime.3 +1 -1
@@ -131,7 +131,7 @@ .SH EXAMPLES struct rpc_timeval timeout = {1, 0}; struct sockaddr_in name; - memset(&name, 0, sizeof(name)); + bzero(&name, sizeof(name)); sethostent(1); hent = gethostbyname(servername); memcpy(&name.sin_addr, hent\->h_addr, hent\->h_length);
man3/rtnetlink.3 +1 -1
@@ -104,7 +104,7 @@ .SH EXAMPLES int rtnetlink_sk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); -memset(&req, 0, sizeof(req)); +bzero(&req, sizeof(req)); req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.if)); req.nh.nlmsg_flags = NLM_F_REQUEST; req.nh.nlmsg_type = RTM_NEWLINK;
man3/strptime.3 +1 -1
@@ -398,7 +398,7 @@ .SH EXAMPLES struct tm tm; char buf[255]; - memset(&tm, 0, sizeof(tm)); + bzero(&tm, sizeof(tm)); strptime("2001\-11\-12 18:31:01", "%Y\-%m\-%d %H:%M:%S", &tm); strftime(buf, sizeof(buf), "%d %b %Y %H:%M", &tm); puts(buf);
man3const/NULL.3const +1 -1
@@ -62,7 +62,7 @@ .SH CAVEATS .SH BUGS When it is necessary to set a pointer variable to a null pointer, it is not enough to use -.BR memset (3) +.BR bzero (3) to zero the pointer (this is usually done when zeroing a struct that contains pointers), since ISO C and POSIX don't guarantee that a bit pattern of all 0s
man3type/size_t.3type +1 -0
@@ -173,6 +173,7 @@ .SH SEE ALSO .BR fwrite (3), .BR memcmp (3), .BR memcpy (3), +.BR bzero (3), .BR memset (3), .BR offsetof (3), .BR ptrdiff_t (3type)
man3type/void.3type +1 -0
@@ -71,5 +71,6 @@ .SH SEE ALSO .BR malloc (3), .BR memcmp (3), .BR memcpy (3), +.BR bzero (3), .BR memset (3), .BR intptr_t (3type)
man7/aio.7 +1 -1
@@ -145,7 +145,7 @@ .SH STANDARDS POSIX.1-2001, POSIX.1-2008. .SH NOTES It is a good idea to zero out the control block buffer before use (see -.BR memset (3)). +.BR bzero (3)). The control block buffer and the buffer pointed to by .I aio_buf must not be changed while the I/O operation is in progress.
man7/netlink.7 +2 -2
@@ -539,7 +539,7 @@ .SH EXAMPLES .EX struct sockaddr_nl sa; -memset(&sa, 0, sizeof(sa)); +bzero(&sa, sizeof(sa)); sa.nl_family = AF_NETLINK; sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
@@ -561,7 +561,7 @@ .SH EXAMPLES struct msghdr msg; msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; -memset(&sa, 0, sizeof(sa)); +bzero(&sa, sizeof(sa)); sa.nl_family = AF_NETLINK; nh\->nlmsg_pid = 0; nh\->nlmsg_seq = ++sequence_number;
man7/unix.7 +3 -3
@@ -912,7 +912,7 @@ .SH BUGS addrp = malloc(addrlen + 1); if (addrp == NULL) /* Handle error */ ; -memset(addrp, 0, addrlen + 1); +bzero(addrp, addrlen + 1); if (getsockname(sfd, (struct sockaddr *) addrp, &addrlen)) == \-1) /* handle error */ ;
@@ -1004,7 +1004,7 @@ .SS Program source * the structure. */ - memset(&name, 0, sizeof(name)); + bzero(&name, sizeof(name)); /* Bind socket to socket name. */
@@ -1137,7 +1137,7 @@ .SS Program source * the structure. */ - memset(&addr, 0, sizeof(addr)); + bzero(&addr, sizeof(addr)); /* Connect socket to socket address. */
Signature · 1 line
2.39.0
Quoted 6 lines · Alejandro Colomar via Libc-alpha
bzero(3) is simpler to use, and can avoid silly mistakes that are hard to spot. memset(3), while it is necessary in a few very-specific cases, should be avoided when the memory is to be zeroed.
POSIX and ISO can say otherwise, but it doesn't make any sense to recommend using memset(3) over bzero(3).
bzero is deprecated by POSIX.1-2001, removed by POSIX.1-2008, and on glibc implementation now calls memset (previously some architecture added ifunc redirection to optimized bzero to avoid the extra function call, it was removed from all architectures).
Also, GCC for some time also replaces bzero with memset so there is no gain in actually call bzero (check glibc commit 9403b71ae97e3f1a91c796ddcbb4e6f044434734).
Quoted 10 lines · Adhemerval Zanella Netto via Libc-alpha
Quoted 6 lines · Alejandro Colomar via Libc-alpha
bzero(3) is simpler to use, and can avoid silly mistakes that are hard to spot. memset(3), while it is necessary in a few very-specific cases, should be avoided when the memory is to be zeroed.
POSIX and ISO can say otherwise, but it doesn't make any sense to recommend using memset(3) over bzero(3).
Quoted 7 lines
bzero is deprecated by POSIX.1-2001, removed by POSIX.1-2008, and on glibc implementation now calls memset (previously some architecture added ifunc redirection to optimized bzero to avoid the extra function call, it was removed from all architectures).
Also, GCC for some time also replaces bzero with memset so there is no gain in actually call bzero (check glibc commit
9403b71ae97e3f1a91c796ddcbb4e6f044434734).
In addition, gcc -Wall warns if you mistakenly pass 0 as memset's 3rd arg, which undercuts the argument that bzero avoids silly mistakes.
Re: [PATCH] bind.2, mount_setattr.2, openat2.2, perf_event_open.2, pidfd_send_signal.2, recvmmsg.2, seccomp_unotify.2, select_tut.2, sendmmsg.2, set_thread_area.2, sysctl.2, bzero.3, getaddrinfo.3, getaddrinfo_a.3, getutent.3, mbrtowc.3, mbsinit.3, rti...
Hi,
Quoted 7 lines
Quoted 7 lines
bzero is deprecated by POSIX.1-2001, removed by POSIX.1-2008, and on glibc implementation now calls memset (previously some architecture added ifunc redirection to optimized bzero to avoid the extra function call, it was removed from all architectures).
Also, GCC for some time also replaces bzero with memset so there is no gain in actually call bzero (check glibc commit
9403b71ae97e3f1a91c796ddcbb4e6f044434734).
Agreed, there is no benefit from using it, and certainly no reason to try to undo its removal. We should promote standards, not try to subvert them... A more productive way would be to propose new functions to the C/C++ committees.
Quoted 2 lines
In addition, gcc -Wall warns if you mistakenly pass 0 as memset's 3rd arg, which undercuts the argument that bzero avoids silly mistakes.
Also I think GCC should give a deprecated/obsolete warning (or perhaps error?) when using bzero, bcmp, bcopy, index, rindex etc so people can start removing the few remaining uses from ancient code.
Cheers,
Wilco
Re: [PATCH] bind.2, mount_setattr.2, openat2.2, perf_event_open.2, pidfd_send_signal.2, recvmmsg.2, seccomp_unotify.2, select_tut.2, sendmmsg.2, set_thread_area.2, sysctl.2, bzero.3, getaddrinfo.3, getaddrinfo_a.3, getutent.3, mbrtowc.3, mbsinit.3, rti...
Hi Wilco, Paul, and Adhemerval,
Quoted 6 lines · Wilco Dijkstra
Hi,
Quoted 4 lines
Quoted 4 lines
bzero is deprecated by POSIX.1-2001, removed by POSIX.1-2008, and on glibc implementation now calls memset (previously some architecture added ifunc redirection to optimized bzero to avoid the extra function call, it was removed from all architectures).
Sure, POSIX prefers memset(3). But why? "Because it is standard" isn't a valid reasoning, because POSIX decides what is standard, so it would be circular reasoning.
Anyway, the fact that libc doesn't provide it is not a problem for callers: the compiler provides it. And even if the compiler dropped support, one can write it with a one liner, which even POSIX once recommended[1]:
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
[1]: <https://pubs.opengroup.org/onlinepubs/009695399/functions/bzero.html>
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Also, GCC for some time also replaces bzero with memset so there is no gain in actually call bzero (check glibc commit
9403b71ae97e3f1a91c796ddcbb4e6f044434734).
No gain in generated code; but there's a gain in source code: less cognitive load. Instead of 3 arguments, the order of which is not easy to remember, the programmer only needs to care about 2, and they're obvious.
Quoted 3 lines
Agreed, there is no benefit from using it, and certainly no reason to try to undo its removal. We should promote standards, not try to subvert them...
I generally promote POSIX; but at the same time I'm not blindly following it, and when its decisions don't make sense I will deviate from it.
Quoted 2 lines
A more productive way would be to propose new functions to the C/C++ committees.
I believe in existing practice as a way of improving the standards. IMO, it doesn't make sense to ask POSIX to add a function, if no-one uses it.
So I think it should be fine to recommend using a well designed API, and use that as a way to increase its use, hopefully resulting long-term in a reincorporation to POSIX.
I also defend mempcpy(3) over any POSIX or ISO alternatives. It's simply superior to the alternatives, and POSIX should standardize it (and I'd say even deprecate memcpy(3), which is a misdesigned API, but I won't go that far for now).
Quoted 7 lines
Quoted 3 lines
In addition, gcc -Wall warns if you mistakenly pass 0 as memset's 3rd arg, which undercuts the argument that bzero avoids silly mistakes.
Also I think GCC should give a deprecated/obsolete warning (or perhaps error?) when using bzero, bcmp, bcopy, index, rindex etc so people can start removing the few remaining uses from ancient code.
There are many users of bzero(3) in the wild, and it is a fine API from a usability point of view. Not being promoted by POSIX or ISO is not enough to warn about its use. With that reasoning, we should warn about many GNU extensions, and some of them are really fine (so much that many ended up in POSIX).
However, it would be fine to warn about those that are error-prone:
- bcopy(3)
And also warn about those that have a drop-in replacement in POSIX:
- bcmp(3) - index(3) - rindex(3)
I would endorse warning about those. BTW, I'll rewrite the bcmp(3) page to say it's identical to memcmp(3).
Quoted 3 lines
Cheers,
Wilco
Cheers,
Alex
Signature · 1 line
<http://www.alejandro-colomar.es/>
Re: [PATCH] bind.2, mount_setattr.2, openat2.2, perf_event_open.2, pidfd_send_signal.2, recvmmsg.2, seccomp_unotify.2, select_tut.2, sendmmsg.2, set_thread_area.2, sysctl.2, bzero.3, getaddrinfo.3, getaddrinfo_a.3, getutent.3, mbrtowc.3, mbsinit.3, rti...
In reply to Wilco DijkstraHi Alex,
Quoted 3 lines
That's a good counterargument for the silly mistakes point. But the cognitive load that programmers need to care about the extra useless argument for no good reason is still a problem of the memset(3) API that bszero(3) simply hasn't.
There is also the cognitive load of having to learn yet another interface. There is also the overhead of libraries having to implement yet another function. Plus compilers optimizing it. Maintaining, testing, and documenting it. And so on.
Why would anyone invest all this effort if there isn't a significant gain after all that? So a new interface must be significantly and measurably better to be worth all this work. More than 20 years ago people decided that it is not worth it for bzero and various other functions given they have almost identical equivalents in the C standard which were already supported on all targets and in most cases better optimized. One of the most common portability issues was the lack of bcopy and bzero which lead to hacky and buggy workarounds.
Quoted 3 lines
I'd like to get a rationale for why we should promote strnlen(3) but not bzero(3) that doesn't reduce to "it is standard". Why would the standard cover on and not the other?
Firstly memchr is not an equivalent of strnlen, it would be something like:
tmp = memchr (p, '\0', n);
len = (tmp == NULL) ? n : tmp - p;
Be honest, would you really prefer writing that over strnlen (p)?
And neither does memchr have the same performance. Searching for zero is typically faster than searching for any character, so a well optimized strnlen should beat memchr. Note that doesn't mean it is unreasonable for a generic strnlen to call memchr - one typically starts optimizing the C standard functions, and generic string functions use those as primitives if no optimized version is available (yet).
An optimized bzero function wouldn't be faster than memset - while you might need a check for zero (or duplicate the input byte), that is a small overhead that is hard to measure on modern hardware. We had a proposal for adding memzero/memclr/ memclear/memset0/memset_zero/... a while back so I measured it and concluded there is just no benefit. A few decades ago I was programming on an 8MHz in-order core and every single cycle&byte mattered then, but it's a very different world today!
Cheers,
Wilco
Hi Paul,
Quoted 16 lines · Paul Eggert
Quoted 15 lines · Adhemerval Zanella Netto via Libc-alpha
Quoted 6 lines · Alejandro Colomar via Libc-alpha
bzero(3) is simpler to use, and can avoid silly mistakes that are hard to spot. memset(3), while it is necessary in a few very-specific cases, should be avoided when the memory is to be zeroed.
POSIX and ISO can say otherwise, but it doesn't make any sense to recommend using memset(3) over bzero(3).
bzero is deprecated by POSIX.1-2001, removed by POSIX.1-2008, and on glibc implementation now calls memset (previously some architecture added ifunc redirection to optimized bzero to avoid the extra function call, it was removed from all architectures).
Quoted 4 lines
Quoted 2 lines
Also, GCC for some time also replaces bzero with memset so there is no gain in actually call bzero (check glibc commit
9403b71ae97e3f1a91c796ddcbb4e6f044434734).In addition, gcc -Wall warns if you mistakenly pass 0 as memset's 3rd arg, which undercuts the argument that bzero avoids silly mistakes.
That's a good counterargument for the silly mistakes point. But the cognitive load that programmers need to care about the extra useless argument for no good reason is still a problem of the memset(3) API that bszero(3) simply hasn't.
If it's about defending a minimal set of functions that serve the basic purposes that programmer may need, I'll prepare a counterargument:
Why does POSIX have strnlen(3)? strnlen(s, n) is just a shorthand for memchr(s, '\0', n);
If the similarity wasn't obvious enough, I'll put them together:
strnlen(p, n) ---- memchr(p, 0, n) bzero(p, n) ---- memset(p, 0, n)
I'd like to get a rationale for why we should promote strnlen(3) but not bzero(3) that doesn't reduce to "it is standard". Why would the standard cover on and not the other?
Cheers,
Alex
Quoted 1 line
Signature · 1 line
<http://www.alejandro-colomar.es/>
Quoted 10 lines · Adhemerval Zanella Netto via Libc-alpha
Quoted 6 lines · Alejandro Colomar via Libc-alpha
bzero(3) is simpler to use, and can avoid silly mistakes that are hard to spot. memset(3), while it is necessary in a few very-specific cases, should be avoided when the memory is to be zeroed.
POSIX and ISO can say otherwise, but it doesn't make any sense to recommend using memset(3) over bzero(3).
Quoted 7 lines
bzero is deprecated by POSIX.1-2001, removed by POSIX.1-2008, and on glibc implementation now calls memset (previously some architecture added ifunc redirection to optimized bzero to avoid the extra function call, it was removed from all architectures).
Also, GCC for some time also replaces bzero with memset so there is no gain in actually call bzero (check glibc commit
9403b71ae97e3f1a91c796ddcbb4e6f044434734).
This whole s/memset/bzero/g patchset seems like a lot of busywork that doesn't seem to bring any real benefit. I would agree with the rest here and just drop this. That's just going to add confusion to the manpages.