当前位置: 首页 > news >正文

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
whereT: 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"));
http://www.lryc.cn/news/130545.html

相关文章:

  • 公网远程连接Redis数据库详解
  • 天津报web前端培训班一定要选贵的吗?
  • iptables学习笔记
  • Express 实战(一):概览
  • SpringBoot中的可扩展接口
  • 中大型无人机远程VHF语音电台系统方案
  • 数字孪生和SCADA有哪些区别?
  • [bug] 记录version `GLIBCXX_3.4.29‘ not found 解决方法
  • git 回滚相关问题
  • SQL力扣练习(十一)
  • 如何将常用的jdbc方法封装起来???
  • 【1day】复现任我行协同CRM存在SQL注入漏洞
  • 3D虚拟形象数字替身的制作及应用介绍
  • Spring中JavaBean的生命周期及模式
  • Qt5开发环境-银河麒麟V10ARM平台
  • 「Qt」文件读写操作
  • 0101前期准备-大数据学习
  • TypeScript教程(四)基本运算符
  • 计算机网络的性能指标
  • BBS项目day04 文章详情页、点赞点菜、评论功能
  • el-table分页后序号连续的两种方法
  • Nginx反向代理技巧
  • kafka--kafka的基本概念-副本概念replica
  • css伪元素实现li列表圆点相连+锚点跳转悬浮窗实现
  • IronPDF for .NET Crack
  • 【C++进阶】继承、多态的详解(多态篇)
  • excel快速选择数据、选择性粘贴、冻结单元格
  • 【数仓建设系列之一】什么是数据仓库?
  • Vue2-配置脚手架、分析脚手架、render函数、ref属性、props配置项、mixin配置项、scoped样式、插件
  • VS2015项目中,MFC内存中调用DLL函数(VC6生成的示例DLL)