Rust 1.45修复存在已久的类别转型bug

Mozilla主导开发的通用程序语言Rust,推出了最新的1.45稳定版,这个版本有两大重点,第一个是修复将大浮点数转换成小整数,可能出现的未定义行为问题,另一个则是让Rust热门网页开发框架Rocket,长期使用的Nightly功能进入稳定阶段。

Rust 1.45这次修复的类别转型问题,早在2013年10月就已经被发现了。由于rustc使用LLVM作为编译器后端,当开发者在程序代码中使用强制转换Cast函数时,底层其实是以LLVM的fptoui来实例强制转换,fptoui是浮点数到无号整数(Floating Point To Unsigned Integer)的缩写,而fptoui指令在部分情况可能产生有问题的值,当开发者将较大的浮点数,强制转换成较小的整数,则将产生未定义的行为。

官方以下图的例子解释,在Rust 1.44中尝试打印x:0,则可能打印出任意内容或是执行任意运算,但是在这个范例程序代码中,并没有不安全的程序代码,官方提到,这就是他们把这个bug命名为健全(Soundness)的原因,因为是编译器执行了错误的处理,这个bug之所以花了很长的时间才解决,是因为他们无法确定怎样的解决方式才是正确的方向。

最后官方决定,在使用as的时候,将执行饱和强制转换(Saturating Cast),而这将会把太大的浮点数,转换成尽可能大的值,太小的浮点数则转换成尽可能小的数值,而NaN则产生0。官方还提供了另一种方法,当开发者想要跳过检查,也可以使用一组新加入的不安全强制转换方法,不过官方提到,开发者应该把这个方法当作最后选择,而且编译器通常可以优化检查程序,所以最终安全和不安全的版本性能是相同的。

Rust 1.45第二个更新重点,是能够在更多地方使用类似函数程序的宏,而这将连带使得Rocket框架受益。Rocket是2016年底发布的网页框架,被称作Rust生态系统中必备的最佳框架,可在不牺牲弹性、可用性和类型安全的情况下,让开发者快速开发出安全的网页应用程序。

开发者在Rust 1.45中,可以于表达式(Expression)、模式(Pattern)和陈述式(Statement)位置调用宏,这是一个提升开发方便性的调整,而Rocket也因此可以不再依靠Nightly功能,因为Rust 1.45,Rocket将不包含任何Rust的Nightly功能,使得Rocket进入更加稳定的阶段。