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?

Functions