In C11, K.3.7.4.1 The memset_s function, I found this bit of rather confusing text:
Unlike
memset
, any call to thememset_s
function shall be evaluated strictly according to the rules of the abstract machine as described in (5.1.2.3). That is, any call to thememset_s
function shall assume that the memory indicated bys
andn
may be accessible in the future and thus must contain the values indicated byc
.
This implies that memset
is not (necessarily) "evaluated strictly according to the rules of the abstract machine". (The chapter referenced is 5.1.2.3 Program execution.)
I fail to understand the leeway the standard gives to memset
that is explicitly ruled out here for memset_s
, and what that would mean for an implementor of either function.
The memset() function sets the first count bytes of dest to the value c . The value of c is converted to an unsigned character. The memset() function returns a pointer to dest .
Bzero is non-standard and portable while memset is. memset has the same features as bzero but more. With memset the setting of the bytes does not have to be zero. It can be any signed int.
All zeroing operations that the pool allocator performs and many structure/array initializations that InitAll performs end up going through the memset function. Memset is one of the hottest functions on the operating system and is already quite optimized as a result.
C library function - memset() The C library function void *memset(void *str, int c, size_t n) copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str.
Imagine you have read a password:
{
char password[128];
if (fgets(password, sizeof(password), stdin) != 0)
{
password[strcspn(password), "\n\r"]) = '\0';
validate_password(password);
memset(password, '\0', sizeof(password));
}
}
You've carefully zapped the password so it can't be found accidentally.
Unfortunately, the compiler is allowed to omit that memset()
call because password
is not used again. The rule for memset_s()
means that the call cannot be omitted; the password
variable must be zeroed, regardless of optimization.
memset_s(password, sizeof(password), '\0', sizeof(password));
This is one of the few really useful features in Annex K. (We can debate the merits of having to repeat the size. However, in a more general case, the second size can be a variable, not a constant, and then the first size becomes a runtime protection against the variable being out of control.)
Note that this requirement is placed on the compiler rather than the library. The memset_s()
function will behave correctly if it is called, just as memset()
will behave correctly if it is called. The rule under discussion says that the compiler must call memset_s()
, even though it may be able omit the call to memset()
because the variable is never used again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With