Crate totally_sound_ptr_int_cast
source · [−]Expand description
why is this sound
To withstand this future I’m raving about in the readme, we return to the old ways.
C defines the printf
format specifier p
something like
The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
and the scanf
format specifier p
like
Matches an implementation-defined set of sequences, which should be the same as the set of sequences that may be produced by the %p conversion of the fprintf function. The corresponding argument shall be a pointer to a pointer to void. The input item is converted to a pointer value in an implementation-defined manner. If the input item is a value converted earlier during the same program execution, the pointer that results shall compare equal to that value; otherwise the behavior of the %p conversion is undefined.
Once you’re at “shall compare equal”, you pretty much can’t get out
of the pointers being usable interchangeably, or the wording for
casting to void*
and back doesn’t work.
We additionally note that glibc documents that non-null pointers are printed as hex integers. I’m pretty sure musl does about the same thing but I haven’t tested with musl.
So, we %p
-print a pointer and parse the result as an integer and
there’s our very defensible integer representation of a pointer. For
the inverse, we print the integer in that exact hexadecimal form,
and then %p
-parse it back into a pointer, and we have the great,
very defensible argument that we can actually use this pointer
because that’s what the scanf
docs say. The rust memory model
can hardly say that C stops working as defined, right?