5 ms·
Isn't memset different in that it's an external function that compiler writers have chosen to intercept and perform themselves? Why is saying 'use memset_s' acc
by secondcoming 5y ago
Isn't memset different in that it's an external function that compiler writers have chosen to intercept and perform themselves? Why is saying 'use memset_s' acceptable when they could have stopped treating memset as a special case?
- chrisseaton 5y ago> Isn't memset different in that it's an external function that compiler writers have chosen to intercept and perform themselves? The semantics of memset and memset_s are defined by a standard. They're not unknown functions that could do anything, and they're breaking a rule by treating them differently, like you're suggesting they are.
- Someone 5y agoIf you include a standard header (using <> brackets) and call a function that the standard says get declared when doing that, the compiler is allowed to assume you want the standard behavior, and inline that/replace it by a specialized version/etc. Optimizing memset, in particular, can reap huge benefits, for example for sizes of 4 or 8 bytes in tight loops or for zeroing cache line sized blocks.
- halayli 5y agomemset is not a special case. Compiler designers are very much against special casing, and rightfully so. Compilers do have an intrinsic equivalent but that has nothing to do with whether it gets optimized out or kept. Following SSA rules, if you are writing to a non-volatile memory and not reading from it for the remaining duration of its lifetime then it's dead code. use memset_s was a suggestion if your goal is to scrub memory because it guarantees the write will happen. The guarantee comes from the C standard: > Unlike memset, any call to the memset_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 the memset_s function shall assume that the memory indicated by s and n may be accessible in the future and thus must contain the values indicated by c Which essentially means treat the memory as-if it's volatile.
- 1ris 5y agoAre you allowed to cast the void * to volatile void *, pass that to memset and except the same result, or is the void *, volatile void*, void * conversion eliminated aswell?
- ncmncm 5y agoYou can wave whichever dead chickens you like over the keyboard, all to the same effect. The compiler ensures only semantics that are observable. If you pass a pointer to a volatile or atomic object to another function the compiler cannot see into, the compiler knows that any specified operations might be observable, so must act accordingly. Then, operations on that object will not be optimized away. Or, anyway, not until someone builds the program using Link Time Optimization ("-flto") and the called function body becomes visible.
- 1ris 5y agoI'm confused. Is the memset to the temporary volatile void* observable or not, and is the temporary possibly eliminated?
- ncmncm 5y agoCasting the pointer passed to memset has no effect. The compiler knows what the storage pointed-to is: a temporary object. The compiler knows that memset does not allow a pointer to the object to escape from view. So, it can eliminate the call. Calling C11's memset_s, or MS's SecureZeroMemory, or FreeBSD's explicit_bzero, has the effect, to the compiler, of making the object observable, so that operations on it will not be optimized away. There is no way to express this locally within the language; you must rely on facilities provided by a Standard or your platform, or on the dodgy linkage trick cited elsewhere.
- halayli 5y agovolatile is a type qualifier and can be casted. However, memset's declaration takes a void* which prevents you from passing a volatile void*. casting or not won't change anything in this case because what matters is what memset takes and not what the pointer's fully qualified type is prior to calling memset. From the compiler's perspective, you're passing a non-volatile pointer to memset which makes it a candidate for elimination if the pointer's lifetime ends after memset call.