Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use '\0' instead of 0 for memset?

Tags:

c++

c

According to the this Unix documentation http://pubs.opengroup.org/onlinepubs/009695399/functions/bzero.html

The memset() function is preferred over bzero().

For maximum portability, it is recommended to replace 
the function call to bzero() as follows:

#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)


But void *memset(void *s, int c, size_t n); second arg is an int so why are they recommending '\0' instead of 0? The memset() doc says "The memset() function shall copy c (converted to an unsigned char) arg into each of the first n bytes of the object pointed to by s." Is this more efficient or simply more explicit? Is there a best practice involved here?

like image 850
joemooney Avatar asked Dec 26 '22 08:12

joemooney


2 Answers

second arg is an int so why are they recommending '\0' instead of 0?

To make it clear the thing is going to end up as a NUL character; after all memset will convert it to unsigned char. This is just a matter of style, because '\0' has type int and is thus the same as 0.

like image 79
Fred Foo Avatar answered Jan 09 '23 23:01

Fred Foo


Is it more efficient?

In a way: bzero was never actually part of the standard. That's why the page you link to recommends using memset. So using memset is more efficient in the sense that you can rest assured that your code compiles on all standard C compilers.

'\0' instead of 0
The standard requires that a char can be safely converted to an int:

Both the basic source and basic execution character sets shall have the following members:
[...]
the 10 decimal digits
0 1 2 3 4 5 6 7 8 9
[...]
In both the source and execution basic character sets, the value of each character after 0 in the above list of decimal digits shall be one greater than the value of the previous.

So passing '\0' to an int param is not a problem. What's more: you are passing a zero-escape-sequence, which is actually the same as passing 0.
It is, however, more explicit: memset will initialize N bytes to whatever value you pass to it. The only type in C that is guaranteed to be 1 and only 1 byte big, is the char type.

So:

memset(some_ptr, 0, 12);
//is, in practice identical to:
memset(some_ptr, '\0', 12);

But seeing as you're setting 12 bytes, passing a value of a 1-byte-big type better reflects this. I prefer passing a char explicitly for that reason, but it's up to you.

History of memset:
The function memset has been around for ages. In fact, it existed back in the days the function prototypes!

Another thing to keep in mind is how character literals in C, by themselves, are, like most any literal value, ints.

like image 37
Elias Van Ootegem Avatar answered Jan 09 '23 23:01

Elias Van Ootegem