Hi Branden, Wilco, On 1/4/23 21:19, G. Branden Robinson wrote: > Since I'm CCed on this I'll chuck in two cents... > > At 2023-01-04T19:41:30+0000, Wilco Dijkstra wrote: >>> bzero(3) is much more useful than memset(3).  I've only used >>> memset(3) for something non-zero once in my life, IIRC.  Writing >>> bzero(p, n) is easier to get right, and simpler. >> >> It may save a few keypresses but it's dead so all you're doing is >> confuse people who have never heard of it... I forgot to add a reference in my previous message. I wanted to link to this stackoverflow answer: Some relevant quote from there: """ 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 agree with Wilco here. My understanding is that memset(), memcpy(), > and memmove() are almost C language primitives masquerading as function > calls, in that the language is _unimplementable_, even in a freestanding > environment, without them. (How are you going to copy a struct? How > are you going to work safely with hunks of allocated memory?[1]) memcpy() is a useless function. You could replace _every_ single call to it by mempcpy(3), and you wouldn't loose a single bit of performace (assuming equally-optimized implementations). And mempcpy(3) has use cases that memcpy(3) can't cover without adding an extra +len operation. memset(3): alright, it allows doing more things than bzero(3). So, yes, in the end, you need to implement memset(3) unconditionally in glibc, but can implement bzero(3) either in glibc or in the compiler, and can be implemented as a thin wrapper around memset(3). However, when was the last time you used it for setting "mem" to anything other than 0? I've only done that exactly once in my life. I don't remember the exact details, but I needed to set something to 1s. > > The line between language runtime services and operating system > services is fuzzy in C, at least as the the language is presented and > taught. Slowly, over time, that line is being clarified, to the horror > of those who remember writing C on a PDP-11. > > You can always have your own static function: memclear() or something. static? Do you mean static inline? Or static within a .c file? Most projects I've worked in, either call bzero(3) directly, or define a macro memzero() that is effectively memset(mem, 0, size) or memset(mem, size, 0) (I didn't care to check the manual page, because my point is exactly that: I don't remember, both look reasonably good). > > The b in bzero() or for Bad BSD Bogosity. Ban it. :P Like index() and > rindex() it is duplicative. Okay, let's call it memzero() if you prefer :) > > Regards, > Branden > > [1] That last point may be contrived. For many years, no one cared. Cheers, Alex --