Unsafe Rust 能做什么
在不安全的 Rust 中唯一不同的是,你可以:
- 对原始指针进行解引用
- 调用“不安全”的函数(包括 C 函数、编译器的内建指令和原始分配器。
- 实现“不安全”的特性
- 改变静态数据
- 访问“union”的字段
这就是所有了。这些操作被归入不安全操作的原因是,误用其中的任何一项都会引起可怕的未定义行为。调用“未定义行为”使编译器有充分的权利对你的程序做任意的坏事。你绝对_不应该_调用“未定义行为”。
与 C 语言不同,Rust 中的“未定义行为”的范围相当有限。核心语言所关心的只是防止以下事情:
- 解除引用(使用
*运算符)悬空或不对齐的指针(见下文) - 破坏指针别名规则
- 调用一个 ABI 错误的函数,或者从一个 unwind ABI 错误的函数中 unwinding
- 引起数据竞争
- 执行用当前执行线程不支持的目标特性编译的代码
- 产生无效的值(无论是单独的还是作为一个复合类型的字段,如
enum/struct/array/tuple)- 一个不是 0 或 1 的
bool - 一个具有无效判别符的“enum”
- 一个空的“fn”指针
- 一个超出[0x0, 0xD7FF]和[0xE000, 0x10FFFF]范围的
char - 一个
!(所有的值对这个类型都是无效的) - 一个从未初始化的内存读出的整数(
i*/u*)、浮点值(f*)或原始指针,或str中的未初始化的内存 - 一个悬空的、不对齐的、或指向无效值的引用/
Box - 一个胖指针、
Box或原始指针,具有无效的元数据:- 如果一个
dyn Trait指针 / 引用指向的 vtable 和对应 Trait 的 vtable 不匹配,那么dyn Trait的元数据是无效的 - 如果 Slice 的长度不是有效的 usize(比如,从未初始化的内存中读取的 usize),那么 Slice 的元数据是无效的
- 如果一个
- 对于一个具有自定义的无效值的类型来说是无效的值(看着有点绕),比如在标准库中的
NonNull和NonZero*(自定义无效值是一个不稳定的特性,但一些稳定的 libstd 类型,如NonNull使用了这个特性)。
- 一个不是 0 或 1 的
“产生”一个值发生在当一个值被分配、传递给一个函数/原始操作或从一个函数/原始操作返回的时候。
如果一个引用/指针是空的,或者它所指向的所有地址并非合法的地址(比如 malloc 分配出的内存),那么它就是悬垂的。它所指向的范围是由指针值和被指向类型的大小决定的(使用size_of_val)。因此,如果指向的范围是空的,悬垂与空是一样的。要注意,切片和字符串指向它们的整个范围,所以它们的长度不可能很大。内存分配的长度、切片和字符串的长度不能大于isize::MAX字节。如果因为某些原因,这太麻烦了,可以考虑使用原始指针。
这就是所有 Rust 中可能会导致未定义行为的原因。当然,不安全的函数和 trait 可以自由地声明任意的其他约束,程序必须保持这些约束以避免未定义行为。例如,分配器 API 声明,释放未分配的内存是未定义行为。
然而,对这些约束的违反通常只会导致上述问题中的一个,一些额外的约束也可能来自于编译器的内在因素,这些因素对代码如何被优化做出了特殊的假设。例如,Vec 和 Box 使用了内建指令,要求他们的指针在任何时候都是非空的。
Rust 在其他方面对其他可疑的操作是相当宽容的。Rust 认为以下情况是“安全的”:
- 死锁
- 有一个数据竞争
- 内存泄漏
- 未能调用解构器
- 整数溢出
- 中止程序
- 删除生产数据库
然而任何真正可能做这种事情的程序都是_可能_不正确的,Rust 提供了很多工具来尽可能检查出这些问题,但要这些问题完全被预防是不现实的。
Unsafe Rust 能做什么的更多相关文章
- Rust入坑指南:居安思危
任何事情都是相对的,就像Rust给我们的印象一直是安全.快速,但实际上,完全的安全是不可能实现的.因此,Rust中也是会有不安全的代码的. 严格来讲,Rust语言可以分为Safe Rust和Unsaf ...
- Rust 阴阳谜题,及纯基于代码的分析与化简
Rust 阴阳谜题,及纯基于代码的分析与化简 雾雨魔法店专栏 https://zhuanlan.zhihu.com/marisa 来源 https://zhuanlan.zhihu.com/p/522 ...
- 我持续推动Rust语言支持Windows XP系统
前言 Rust好像长期以来不支持Windows XP系统.有不少用户发帖提议官方支持XP,基本上都被Rust官方开发人员明白的拒绝了.他们的对话大致上是以这种形式開始和结束的(当中乙方代表官方及其拥趸 ...
- 全面认识 RUST -- 掌控未来的雷电
文章目录 RUST 简介 如何衡量语言的好坏? 静态语言 编译器 语言定位 代表性项目 Hello World RUST 前景 RUST 简介 Rust 是一种兼顾内存安全.高并发和稳定运行的编程语言 ...
- rust学习
Rust (github) 1. install (https://rustup.rs/) 2. play on line curl https://sh.rustup.rs -sSf | sh e ...
- 005-多线程-锁-JUC锁-LockSupport【使用、Unsafe、对比Object的wait、底层源码】
一.概述 在Java多线程中,当需要阻塞或者唤醒一个线程时,都会使用LockSupport工具类来完成相应的工作.LockSupport定义了一组公共静态方法,这些方法提供了最基本的线程阻塞和唤醒功能 ...
- JUC整理笔记一之细说Unsafe
JUC(java.util.concurrent)的开始,可以说是从Unsafe类开始. Unsafe 简介 Unsafe在sun.misc 下,顾名思义,这是一个不安全的类,因为Unsafe类所操作 ...
- 一个名为不安全的类Unsafe
最近为了更加深入了解NIO的实现原理,学习NIO的源码时,遇到了一个问题.即在WindowsSelectorImpl中的 pollWrapper属性,当我点进去查看它的PollArrayWrapper ...
- 4.1 python中调用rust程序
概述 使用rust-cpython将rust程序做为python模块调用: 通常为了提高python的性能: 参考 https://github.com/dgrunwald/rust-cpython ...
随机推荐
- Glob 语法及解析
Glob 语法及解析 目录 1. glob 简介 2. glob 语法 3. .gitignore 4. Python glob 1 glob 简介 glob 是用于匹配符合指定模式的文件集合的一种语 ...
- Python:Dict
0.运算符 in:检查字典中是否有某个key 'a' in {'a':1,'b':2} True 提取其中Key对应的Value: d={'1':'A','2':'B','3':'C'} d['2'] ...
- 矩池云上安装 NVCaffe教程
使用的是P100,cuda11.1base镜像 创建虚拟环境 conda create -n py36 python=3.6 conda deactivate conda activate py36 ...
- 【Java分享客栈】一个包装过简历的新同事写完微信支付引起事故后果断离职了
前言 挺长时间没发文了,因为公司有一个紧急项目要赶进度,加班如吃饭喝水,久违的进入到码农的状态. 之所以抽空来发个文,是这个项目才刚上线,时间不长却因为一位新同事的代码引起了生产环境的事故,造成了一批 ...
- 30道关于linux的基础命令小题,先练练手
1.修改主机名为yuanlai0224命令是: 2.切换⽬录到/yuchao01/data/,再创建脚本/my_website/scripts/start.sh. 绝对路径.相对路径两种写法 3.查看 ...
- thinkphp 添加数据
....控制器方法返回视图 public function create() { // return view(); } ...............表单页面 <!DOCTYPE html&g ...
- 4、mysql的存储引擎
存储引擎 存储引擎是负责对表中的数据进行提取和写入工作的,我们可以为不同的表设置不同的存储引擎,也就是说不同的表可以有不同的物理存储结构,不同的提取和写入方式. 1.1 InnoDB 引擎:具备外键支 ...
- Ubuntu系统中防火墙的使用和开放端口
目录 Ubuntu系统 防火墙的使用和开放端口 1.安装防火墙 2.查看防火墙状态 3.开启.重启.关闭防火墙 4.Ubuntu添加开放.关闭端口 5.开放规定协议的端口 6.关闭指定协议端口 7.开 ...
- java-关于java
JavaSE(标准版) JavaME(嵌入式)(淘汰) JavaEE(E企业级开发) JavaSE是基础 API端口 JDK Java开发工具 JRE Java运行时环境 JVM 虚拟机 可以在软件和 ...
- Linux上后台保持Terminal交互运行的三种方式:nohub、screen和tmux
镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 后台运行 Linux上,如果一个进程需要保持后台运行,尤其是在Linux服务器上,后台运行程序.避免因为SSH连接断开而导致进程停止运行时,该怎么 ...