作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


1.在编译阶段就可以识别出来的溢出

fn main(){
let a : usize = 1;
println!("{}",a-2);
}

执行rustc报以下错误:

rustc usize_test.rs
error: this arithmetic operation will overflow
--> usize_test.rs:4:19
|
4 | println!("{}",a-2);
| ^^^ attempt to compute `1_usize - 2_usize`, which would overflow
|
= note: `#[deny(arithmetic_overflow)]` on by default error: aborting due to previous error

2.运行期溢出

use std::time::{SystemTime, UNIX_EPOCH};

fn main() {
let start = SystemTime::now();
let since_the_epoch = start
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
let ts = since_the_epoch.as_secs() as usize;
//
let a:usize = 1;
let b :usize= ts % 10 + 2;
println!("a={:?}, b={:?}", a,b);
//
println!("{:?}", a-b);
}

当溢出发生的时候,程序panic了:

thread 'main' panicked at 'attempt to subtract with overflow', usize_test_3.rs:16:22
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

由此也说明,rust不是真正的零成本抽象。为了防止无符号整形的溢出,必然需要在减法之前编译进去一个范围判断。

3.如何才能做溢出不panic的减法

use std::time::{SystemTime, UNIX_EPOCH};

fn main() {
let start = SystemTime::now();
let since_the_epoch = start
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
let ts = since_the_epoch.as_secs() as usize;
//
let a:usize = 1;
let b :usize= ts % 10 + 2;
println!("a={:?}, b={:?}", a,b);
//
println!("{:?}", a.wrapping_sub(b));
}

使用wrapping_sub()这个方法。

rust是如此的严谨,情愿使用的时候很啰嗦,也不要在运行时挖坑。

4. 通过release版本跳过溢出检查

在新的目录,执行:cargo new usize_test

在上面的代码写在:usize_test/src/main.rs 中

在usize_test目录执行:cargo build --release

然后执行 usize_test/target/release/usize_test,发现usize类型的溢出已经不会panic了,其结果与执行 wrapping_sub() 一样。

(感谢zhihu网友 @QDelta​ 提醒。)

不过我又陷入了迷惑:

  1. 既然release版本就不检查usize溢出了,还要wrapping_sub()这样的方法干啥?
  2. 对于溢出这样的情况,应该有程序员通过不同的写法来决定如何处理。如果编译个release版本就能跳过,rust又和C/C++有啥区别?

【小测试】rust中的无符号整数溢出的更多相关文章

  1. PHP中使用PDO操作事务的一些小测试

    关于事务的问题,我们就不多解释了,以后在学习 MySQL 的相关内容时再深入的了解.今天我们主要是对 PDO 中操作事务的一些小测试,或许能发现一些比较好玩的内容. 在 MyISAM 上使用事务会怎么 ...

  2. Solidity合约中的整数溢出漏洞事件

    事件 2018年4月23日 BEC 一夜被偷64亿 2018年4月25日 SMT 再爆类似漏洞,火币Pro和OKEx相继暂停了SMT交易 2018年4月25日 BEC.SMT现重大漏洞,这8个智能合约 ...

  3. FinClip小程序+Rust(三):一个加密钱包

    ​ 一个加密货币钱包,主要依赖加密算法构建.这部分逻辑无关iOS还是Android,特别适合用Rust去实现.我们看看如何实现一个生成一个模拟钱包,准备供小程序开发采用 前言 在之前的内容我们介绍了整 ...

  4. 微信小程序开发教程 #043 - 在小程序开发中使用 npm

    本文介绍了如何在微信小程序开发中使用 npm 中包的功能,大大提高微信小程序的开发效率,同时也是微信小程序系列教程的视频版更新. 微信小程序在发布之初没有对 npm 的支持功能,这也是目前很多前端开发 ...

  5. 总结微信小程序开发中遇到的坑

    总结微信小程序开发中遇到的坑,一些坑你得一个一个的跳啊,/(ㄒoㄒ)/~~ 1,页面跳转和参数传递实例 首先说一下我遇到的需求有一个我的消息页面,里面的数据都是后端返回的,返回的数据大致如下,有一个是 ...

  6. 测试开发中Django和Flask框架

    Python测试开发中Django和Flask框架 为了更好地阐述这个问题,我们把开发一个应用的过程进行类比,往往开发一个应用(web应用.系统应用)跟建造房子的过程一样,需要先打地基,搭好骨架,然后 ...

  7. Java架构师中的内存溢出和内存泄露是什么?实际操作案例!

    JAVA中的内存溢出和内存泄露分别是什么,有什么联系和区别,让我们来看一看. 01 内存泄漏 & 内存溢出 1.内存泄漏(memory leak ) 申请了内存用完了不释放,比如一共有 102 ...

  8. 【译】理解Rust中的Futures(二)

    原文标题:Understanding Futures in Rust -- Part 2 原文链接:https://www.viget.com/articles/understanding-futur ...

  9. Rust中的迭代器的使用:map转换、filter过滤、fold聚合、chain链接

    什么是迭代器 Rust中的迭代器是一种强大的工具,它提供了一种灵活.通用的方法来遍历序列.迭代器是实现了Iterator trait的类型,并需要至少实现一个next函数,用于让迭代器指向下一个迭代对 ...

  10. selenium 测试框架中使用grid

    之前的测试框架:http://www.cnblogs.com/tobecrazy/p/4553444.html 配合Jenkins可持续集成:http://www.cnblogs.com/tobecr ...

随机推荐

  1. 人人都会Kubernetes(一):告别手写K8s yaml,运维效率提升500%

    1. Kubernetes的普及和重要性 随着云计算的迅速发展,容器化技术已成为构建和运行分布式应用程序的关键.而Kubernetes作为容器编排领域的佼佼者,已经成为了云原生应用的标准.它不仅简化了 ...

  2. 人工智能聊天DEMO

    import urllib.parse import requests #调用机器人接口 def qingyunke(msg): url = "http://api.qingyunke.co ...

  3. Three.js 入门

    Demo代码地址: https://gitee.com/s0611163/three.js-demo Three.js Three.js下载 从GitHub上下载一个Release版本,https:/ ...

  4. 用 three.js 绘制三维带箭头线

    需求:这个需求是个刚需啊!在一个地铁场景里展示逃生路线,这个路线肯定是要有指示箭头的,为了画这个箭头,我花了不少于十几个小时,总算做出来了,但始终有点问题.我对这个箭头的要求是,无论场景拉近还是拉远, ...

  5. Spark Final-Examination Note

    重点 4567,Special 4,5 3道编程题,分值 35(基本书上,不超纲) 选填各 20分,简答 5 题/25分,编程题 3题/35分. 简答题参考每章课后习题 第 1 章简答题 1. 请阐述 ...

  6. 2016年第七届 蓝桥杯B组C/C++ 决赛题解

    1.一步之遥 从昏迷中醒来,小明发现自己被关在X星球的废矿车里. 矿车停在平直的废弃的轨道上. 他的面前是两个按钮,分别写着"F"和"B". 小明突然记起来,这 ...

  7. VCODE修改控制台编码格式解决输出乱码问题

      中文的windows下的cmd默认使用GBK的编码,敲代码时,页面使用的是UTF-8(65001),而powershell控制台默认使用的是GBK编码(936),用chcp命令可以查看.乱码主要是 ...

  8. 理解 docker volume

    1. docker volume 简介 文章 介绍了 docker image,它由一系列只读层构成,通过 docker image 可以提高镜像构建,存储和分发的效率,节省时间和存储空间.然而 do ...

  9. 8. exporter

    一.已经实现的收集器 1.1 可收集的内存指标 1.2 可收集的jetty指标 二.自定义收集 2.1 summer 2.2 histogram 三.架构设计 exporter作为Prometheus ...

  10. 【C/C++】输出文件的相对路径

    FILE 在有些编译器上会输出带路径的文件名,删除路径可使用函数 strrchr #include <string.h> #include <stdio.h> #define ...