The statement:
volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
Generates a warning C4197 in MSVC v14.1:
There is fundamentally no way to express what the author wants to express. The first version of the code is rightly optimized down to nothing by some compilers, because the underlying object unsigned char x[4]
is not volatile; accessing it through pointer-to-volatile does not magically make it volatile.
The second version of the code is a hack that happens to achieve what the author wants, but at significant additional cost, and in the real world might be counter-productive. If (in a non-toy, fleshed-out example) the array x
had only been used such that the compiler was able to keep it entirely in registers, the hacks in memset_s_volatile_pnt
would force it to be spilled out to actual memory on the stack, only then to be clobbered, and memset_s_volatile_pnt
would not be able to do anything to get rid of the copies in the original registers. A cheaper way to achieve the same thing would be just calling normal memset
on x
, then passing x
to an external function whose definition the compiler can't see (to be safest, an external function in a different shared library).
Safe memory clearing is not expressible in C; it needs compiler/language-level extensions. The best way to do it in C+POSIX is just to do all the handling of sensitive data in a separate process whose lifetime is limited to the duration the sensitive data is needed and rely on memory protection boundaries to ensure it never leaks anywhere else.
If you just want to get rid of the warning, though, the solution is easy. Simply change:
volatile unsigned char * volatile p = (volatile unsigned char * volatile)v;
to:
volatile unsigned char * volatile p = (volatile unsigned char *)v;