2个版本
0.1.1 | 2022年3月31日 |
---|---|
0.1.0 | 2022年3月31日 |
#558 in 音频
7KB
77 行
totally sound ptr<-> int casts
厄运即将来临
好吧,看起来,as
-casts在usize
和原始指针类型之间已经过时。人们正在谈论这些如何使来源变得非常令人烦恼,这对形式化内存模型来说很糟糕。在这个假设的未来,将指针转换为整数可能会变得极其非法,也许通过某些操作系统或FFI API进行往返,然后再将它们转换回整数,最后进行解引用。
可能已经来不及避免这种可怕的命运。在这个注定要失败的时序中,可能有必要使用这个crate来执行完全的ptr<->int转换。
let n = totally_sound_ptr_int_cast::ptr2int(
Bxo::into_raw(your_boxed_stuff.into_raw()));
并且,在同一个程序执行过程中的任何时候,
let p = totally_sound_ptr_int_cast::int2ptr_mut(n);
unsafe { println!("{:?}", &*p); } // or whatever
你都能拿回你的东西。
lib.rs
:
为什么这是可靠的
为了抵御readme中提到的那个未来,我们回归到老方法。
C语言定义了printf
格式说明符p
如下:
参数应该是一个指向void的指针。指针的值将转换为一串打印字符,具体实现方式由实现者定义。
以及scanf
格式说明符p
如下:
匹配实现定义的一组序列,这应该与fprintf函数的%p转换可能产生的序列集相同。相应的参数应该是一个指向void的指针的指针。输入项将以实现定义的方式转换为指针值。如果输入项是在同一程序执行期间之前转换的值,则结果指针应与该值相等;否则,%p转换的行为是未定义的。
一旦你到了“应当比较相等”,你基本上就无法摆脱指针可以互换使用的状态,或者将指针转换为void*
和返回的文法不起作用。
此外,我们注意到glibc文档指出非空指针将被打印为十六进制整数。我相当确定musl也会做同样的事情,但我还没有用musl进行测试。
因此,我们使用%p
打印一个指针,并将结果解析为整数,这就是我们非常可以辩护的指针的整数表示。对于相反的过程,我们将整数以确切的十六进制形式打印出来,然后使用%p
将其解析回指针,我们有非常有力的论据,即我们可以实际使用这个指针,因为这是scanf
文档所说的。Rust内存模型几乎不能说C的定义停止工作,对吧?
依赖项
~43KB