Zapping memory and C++ compatibility

Philip Guenther guenther at
Mon Nov 23 17:52:50 EST 2009

On Mon, Nov 23, 2009 at 8:30 AM, Mike Patnode <mike.patnode at> wrote:
> Without a reference in front of me, I'm fairly certain C style casts are
> mapped to reinterpret_cast in C++.  In this case it's simple syntax
> sugar.  In any case, they are certainly allowed in C++.

No, they are not directly mapped to reinterpret_cast.  They are mapped
to the first option which is legal of a list possibilities that starts
with "just a const_cast" and, IIRC, ends with "just a
reinterpret_cast" with possibilities that include static_cast in the
middle.  (I don't remember the exact list well enough to quote it
here.)  In this case, assuming the original pointer is a 'char *' or
similar, it'll do the combination of a static_cast (from char * to
void *) and a const_cast (from void * to volatile void *).  I.e., the
cast is not the problem.

>> Today's problem is that the last construction isn't valid C++.  We
>> have a test case which tries passing k5-int.h through C++ compiler,
>> and it now fails on Solaris with the native compiler.  It didn't fail
>> before because the macro was never expanded within k5-int.h, but now
>> it gets expanded by the new zapfree() inline function.
>> A possible choice is to make the macro more obviously
>> wishy-washy by explicitly casting ptr back to void *:
>> memset((void *)(volatile void *)ptr, 0, len)

I guess people missed this bit, as it shows that the cast is fine and
that it's the implicit conversion that is rejected by the compiler.
Comparing g++ and gcc's output might make it more obvious:

$ cat f.cpp
#include <string.h>

int main(void)
        char ptr[13];
        int len = 13;
        memset((volatile void *)ptr, 0, len);
        return 0;
$ g++ -c f.cpp
f.cpp: In function `int main()':
f.cpp:7: error: invalid conversion from `volatile void*' to `void*'
$ mv f.cpp f.c
$ gcc -c f.c
f.c: In function `main':
f.c:7: warning: passing arg 1 of `memset' discards qualifiers from
pointer target type

IMO, the 'safe' thing would be to have an actual function
krb5int_zap_data() defined in its own .c file which does the zeroing
out and not mess with volatile at all.  That'll solve it for
file-by-file optimizers.  Whole-program optimizers are at least
theoretically in a position to defeat all work arounds.  Suggestions
for dealing with them would need to come from someone who has access
to one.

Philip Guenther

More information about the krbdev mailing list