 
                            The C99 standards states that:
In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).
This clause gives compilers the right to remove code deemed unused or unneeded when building a program. While this is usually beneficial, sometimes the compiler removes code that it thinks is not needed but has been added with security in mind. An example of this is clearing out the memory of a buffer which is used to store sensitive data. Therefore, care must always be taken when dealing with sensitive data to ensure that operations on it always execute as intended.Insecure compiler optimizations can occur leaving sensitive data (such as passwords or cryptographic keys) in memory.
Non-Compliant Code Example (memset())
...
For all of the below listed compliant code examples, it is strongly recommended that the programmer inspect the generated assembly code to ensure that memory is actually zeroed cleared and none of the function calls were are optimized out.
Non-Compliant Code Example (Touching Memory)
...
Compliant Solution
This compliant solution guarantees, via uses the volatile type qualifier , that memory is actually overwritten and the compiler will not optimize out to help flag to the compiler that the memory should be overwritten and that the call to the memset_s() function should not be optimized out. Unfortunately, this compliant solution may not be as efficient as possible due to the nature of the volatile type qualifier preventing the compiler from optimizing the code at all. Typically, some compilers are smart enough to replace calls to memset() with equivalent assembly instructions which are much more efficient then the memset() implementation. Implementing a memset_s() function as below may prevent the compiler from using the optimal assembly instructions and may result in less efficient code. Check compiler documentation and the assembly output from the compiler.
| Code Block | ||
|---|---|---|
| 
 | ||
| //* memset_s.c */ void *memset_s(void \*v, int c, size_t n) { volatile char *p = v; while (n--) *p++ = c; return v; } //* getPassword.c */ extern void *memset_s(void *v, int c, size_t n); void getPassword() { char pwd[64]; if (retrievePassword(pwd, sizeof(pwd))) { /*checking of password, secure operations, etc \*/ } pwd = memset_s(pwd, 0, sizeof(pwd)); } | 
However, it should be noted that both calling functions and accessing volatile qualified objects can still be optimized out (while maintaining strict conformance to the standard), so the above may still not work.
Risk Assessment
If the compiler optimizes out memory clearing code, an attacker could gain access to sensitive data.
...