首页 > 其他分享 >[Rust] 对整形溢出的处理

[Rust] 对整形溢出的处理

时间:2023-11-05 23:44:39浏览次数:33  
标签:u8 wrapping Rust println 整形 溢出

1. 两种不同模式下的整形溢出

坑了个爹的,书上说的没理解清楚,在Rust程序语言设计中文版3.2中提到了,当使用--release参数进行发布模式构建时,Rust不会检测导致panic的整形溢出,这里需要分两种情况考虑:

  • 编译期就可以发现的整形溢出
  • 程序运行过程中会发生的整形溢出

1.1 编译阶段

如果是编译期能够确定会发生的整形溢出(程序1-1),无论是不是执行了--release参数都会在构建阶段(cargo build)发生报错

// 程序1-1
fn main() {
    let i:u8 = 254;
    let i = i + 4;
    println!("{}!",i);
}

上述变量i的类型为u8类型,值的范围在(0..=255)

经过运算的结果最终的i的值为258,这个值在编译期已经可以检测到整形溢出,最终构建会报错如下:

  • debug模式

    image-20231105214716809

  • release模式

    image-20231105214942664

    这种编译期可以确定的溢出错误,两种模式下都会发生崩溃

1.2 运行阶段

在运行期发生的整形溢出(程序1-2),不会在build阶段报错

// 程序1-2
fn main() {
    let i:u8 = 254;
    for j in 0..=4 {
        println!("{}!",i+j);
    }
}

上述代码,只有在j>1的情况下才会发生整形溢出,这种错误在编译期是发现不了的

  • debug模式执行

    image-20231105220421439

    在不使用--release的时候,在运行阶段报错

  • release模式

    image-20231105220740215

    在使用--release 的情况下,溢出值对256进行了取模运算

1.3 说明

当使用--release进行构建发布模式时,当检测到整形溢出,将会使用一种进制补码包裹(two’s complement wrapping的操作。就是最终的计算出来的结果对2N取模。N为类型的bit位,u8是8位,N=8

2 Rust对溢出的操作

摘自:数据类型 - Rust 程序设计语言 中文版 (rustwiki.org)

要显式处理溢出的可能性,可以使用标准库针对原始数字类型提供的以下一系列方法:

  • 使用 wrapping_* 方法在所有模式下进行包裹,例如 wrapping_add
  • 如果使用 checked_* 方法时发生溢出,则返回 None
  • 使用 overflowing_* 方法返回该值和一个指示是否存在溢出的布尔值
  • 使用 saturating_* 方法使值达到最小值或最大值

这么处理,在debug模式下就不会panic

2.1 wrapping_*

当计算结果发生溢出执行取模操作(程序2-1)

// 2-1
fn main() {
    let i:u8 = 254;
    for j in 2..=4 {
        println!("=======================");
        println!("i+j={}!",i.wrapping_add(j));
        println!("j-i={}!",j.wrapping_sub(i));
        println!("j*i={}!",j.wrapping_mul(i));
        println!("j/i={}!",j.wrapping_div(i));
    }
}

结果如下:

image-20231105222530325

那么问题来了,负数怎么取整?

标签:u8,wrapping,Rust,println,整形,溢出
From: https://www.cnblogs.com/ITY996/p/17811581.html

相关文章

  • 前端开发笔记[5]-rust的webassembly
    摘要基于rust开发webassembly入门,通过rust实现在网页中弹出警告框.rust的webassembly开发方式https://zhuanlan.zhihu.com/p/104299612入门Rust开发WebAssemblyRust编译为WebAssembly在前端项目中使用https://zhuanlan.zhihu.com/p/662991464相对来说,使用Rust开发......
  • 不可靠的 Rust Lifetime Elision
    众所周知,Rust编译器在分析代码的过程中,会对含有引用参数、返回值的函数、方法进行lifetime检查。经历数次版本迭代后Rust编译器发展出了一套惯用规则用于隐式推理lifetime注解(lifetimeelision),从而减小开发者的编写难度,尽可能省略不必要的lifetime注解。由于后文会涉......
  • 【pwn】整数溢出
    这是ctfshow上面的一道题这边v1和v2定义时都是int,有符号整数,想让v1-v2=9,可以考虑负数,但是这个函数过滤了负号 if(strchr(s,45))  return0LL;可以考虑输入比较大的数有符号溢出成负数,输入4294967295的话,就会解析成-1,然后8-(-1)==9就可以看第2个函数:首先int可表示......
  • 国货之光?用Rust编写的Vivo Blue OS
    ❝人生有两出悲剧:一是万念俱灰,另一是踌躇满志。——萧伯纳❞大家好,我是「柒八九」。前言“老乡,老乡,你看东方是不是有一轮朝阳在冉冉升起”。-一个稚嫩的声音从屋子中传来。而此时,一位佝偻着背的秃头老者正在简陋的屋子中,正无精打采的在用字迹早已模糊不清的键盘鼓捣着IDE,从电脑屏......
  • 8. 从零用Rust编写正反向代理, HTTP改造篇之HPACK原理
    wmproxywmproxy是由Rust编写,已实现http/https代理,socks5代理,反向代理,静态文件服务器,内网穿透,配置热更新等,后续将实现websocket代理等,同时会将实现过程分享出来,感兴趣的可以一起造个轮子法项目++wmproxy++gite:https://gitee.com/tickbh/wmproxygithub:https://github.com/tic......
  • Trust
    IsCybersecurityReally(VERY)Important?Peoplesometimesjusttrustthepeopletheycouldtrust,notshould,whichmeanssomebodywhohassomeactualabilitybutdoesn'thaveadegree/match/abilitythey(HR,Manager,Leader,Engineer,Officer,Scho......
  • 与c++比较学习rust3-2:数据类型
    rust的文章在数据类型数据类型标量类型整形,浮点型,布尔型,字符整形c++rustgoint8_ti8int8int16_ti16int16int32_ti32int32int64_ti64int64-i128-intisizeintunsignedintusizeuintuint8_tu8uint8uint16_tu16uint16ui......
  • 与c++比较学习rust3-1:变量和可变性
    rust文章:变量和可变性let,const这两个在c++中,没有与let相同的用法,letlet有点像constauto1.1.相同点:不需要指定类型。使用了constauto之后,不能改变值也不能改变类型。1.2.不同点:rust合法,c++中不合法(即c++中,不能重复定义一个变量)leta=2;leta=4;le......
  • rust 构造器和默认构造器
    构造器和默认构造器Rust中,通常使用一个关联函数new来创建一个对象,通过Defaulttrait来支持默认构造器。//#[derive(Default)]来实现Default,而不必显式的实现。#[derive(Default)]pubstructPerson{name:String,age:u64,}implPerson{//new构造函数......
  • rust 集合当成智能指针
    集合当成智能指针通过为集合实现Dereftrait,提供其拥有和借用的数据视图。Vec是一个拥有T的集合,然后通过实现Deref完成&Vec到&[T]的隐式解引用,从而提供借用T的集合(即&[T])#[stable(feature="rust1",since="1.0.0")]unsafeimpl<#[may_dangle]T,A:Allocator>Dropfor......