Rust: 聊聊AtomicPtr<()>和 *const ()

在Bytes库在github源码(https://docs.rs/bytes/1.1.0/src/bytes/bytes.rs.html#94-100)有关Bytes的定义中,

复制代码
pub struct Bytes {
 	ptr: *const u8,
 	 len: usize, // inlined "trait object"
   	data: AtomicPtr<()>, 
  	 vtable: &'static Vtable,
   }

其中的data字段中有(),一般地,()表示一个空元组。但在这里,是不是这个意思?

我们看到,data可以用这个来赋值:

复制代码
AtomicPtr::new(ptr::null_mut())

那ptr::null_mut()又是啥?查看https://doc.rust-lang.org/stable/std/ptr/fn.null_mut.html,可以看到:

复制代码
pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
    from_raw_parts_mut(invalid_mut(0), ())
}
//再查invaild_mut
pub const fn invalid_mut<T>(addr: usize) -> *mut T {
    // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
    // We use transmute rather than a cast so tools like Miri can tell that this
    // is *not* the same as from_exposed_addr.
    // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
    // pointer).
    unsafe { mem::transmute(addr) }
}

表示:Creates a null mutable raw pointer.类似,创建一个不变的raw pointer有,

复制代码
pub const fn null<T>() -> *const T
where
    T: Thin + ?Sized,

进而,查看https://doc.rust-lang.org/src/core/sync/atomic.rs.html#175,可以了解AtomicPtr的定义,

复制代码
pub struct AtomicPtr<T> {
    p: UnsafeCell<*mut T>,
}

也就是可以了解,Bytes中的data字段是一个用AtomicPtr封装起来的一个函数的可变raw pointer.

当然,上面的data还可以这样赋值:

复制代码
// slice是Box<[u8]>
//let ptr = Box::into_raw(slice) as *mut u8;
//let data = ptr as usize
data: AtomicPtr::new(data as *mut _),

另外,*const ()也自然可以联想到,它可能是表示指向一个固定的函数的raw pointer.

通过下面例子,也可以看到,*const ()与函数指针的转化。

复制代码
fn foo(i32) -> i32 {
    666666
}
fn bar()->String{
    println!("i am bar!");
    String::from("bar")
}

let pointer_1 = foo as *const ();
let pointer_2 = bar as *const ();
let fn_1 = unsafe {
    std::mem::transmute::<*const (), fn(i32) -> i32>(pointer_1)
};
let fn_2 = unsafe {
    std::mem::transmute::<*const (), fn() >(pointer_2)
};
assert_eq!(fn_1(42), 666666);
assert_eq!(fn_2(),String::from("bar"));
相关推荐
爱吃香菜的初学者6 分钟前
十六.Linux——多线程(2)
linux·运维·开发语言
IT_陈寒8 分钟前
Python多进程共享变量这个坑,差点让我加班到凌晨
前端·人工智能·后端
jeo陽19 分钟前
04-循环实战:素数、最大公约数、级数求和与枚举法
c语言·开发语言·数据结构
暖核38 分钟前
kubeadm 集群运维:Worker 节点下线删除、整套集群销毁重建指南
运维·开发语言·php
撸串-研究生40 分钟前
springboot福利院管理系统73979
java·spring boot·后端·福利院管理系统
xixiaoyunya1 小时前
别再写一堆 if-else 了:用策略模式重构你的业务代码
后端
tachibana21 小时前
Go 语言里的 Context 是什么?
开发语言·后端·golang·go·语言
天桥下的卖艺者1 小时前
R语言使用ggcube包轻松绘制文章中的各类3D图形
开发语言·3d·r语言
鶴哥只手遮天2 小时前
Spring Framework 7.0.9 深度剖析-05-配置元数据解析:XML、注解与 JavaConfig
java·后端·开源
鶴哥只手遮天2 小时前
Spring Framework 7.0.9 深度剖析-16-异步与调度
java·后端·开源