zurück zum Artikel

Programmiersprache: Rust 1.45 erweitert prozedurale Makros

Rainald Menge-Sonnentag
Programmiersprache: Rust 1.45 erweitert prozedurale Makros

Funktionsähnliche prozedurale Makros sind neuerdings an zusätzlichen Positionen erlaubt. Außerdem behebt Rust 1.45 ein Problem beim Umwandeln von Zahlen.

Das Rust-Core-Team hat Version 1.45 der Programmiersprache veröffentlicht. Das aktuelle Release bringt zwei wesentliche Neuerungen mit: Zum einen lassen sich funktionsähnliche prozedurale Makros an der Position von Anweisungen (Statements), Ausdrücken (Expressions) und Patterns verwenden. Außerdem hat das Team einen Bug beim Umwandeln von Fließkommazahlen in Integer-Werte behoben.

Beim Cast von Zahlen mit unterschiedlichen Maximal- beziehungsweise Minimalwerten war das Verhalten bisher nicht immer "sound": Die Umwandlung konnte zu unvorhergesehenen Zuständen des Programms führen. Der zugehörige Issue [1] existiert bereits seit 2013 und ist mit dem aktuellen Release geschlossen. Ein Cast von Gleitkommazahlen mit 32 Bit zu 8-Bit-Integer-Werten ohne Vorzeichen wie in

pub fn cast(x: f32) -> u8 {
  x as u8
}

führt für Werte, die kleiner als 0 oder größer als 255 sind zu unvorhergesehenen Ergebnissen. Nun bietet das Team zum Beheben zwei Wege an: Zum einen ist die Umwandlung über as als Saturating Cast umgesetzt, also nach den Regeln der Sättigungsarithmetik. Für obigen Code bedeutet die Neuerung, dass jeder negative Wert 0 als Ergebnis erzeugt und jede Gleitkommazahl, die größer als 255 ist, zum u8-Maximum 255 wird. Auch der Fall f32:NaN (Not a Number) ist abgedeckt und ergibt 0.

Wer auf die Überprüfungen verzichten möchte, kann den unsicheren Weg wählen, der nun aber eine neue Syntax hat und explizit als unsafe gekennzeichnet sein muss:

let x: f32 = 1.0;
let y: u8 = unsafe { x.to_int_unchecked() };

Funktionsähnliche prozedurale Makros kennt die Programmiersprache seit dem Release von Rust 1.30 [2] vor zwei Jahren. Bisher durften sie jedoch nur alleine und außerhalb von Funktionen stehen. Die aktuelle Version erlaubt ihren Einsatz darüber hinaus an der Position von Ausdrücken, Patterns und Anweisungen, wie in folgendem Codebeispiel aus dem Rust-Blog zu einem Makro mit dem Namen mac:

// imagine we have a procedural macro named "mac"

mac!(); // item position, this was what was stable before

// but these three are new:
fn main() {
  let expr = mac!(); // expression position

  match expr {
      mac!() => {} // pattern position
  }

  mac!(); // statement position
}

Die Ergänzung zielt weniger auf den allgemeinen Einsatz in Rust-Programmen und mehr auf das Webframework Rocket [3] für Rust, das derzeit in Version 0.4 verfügbar ist.

Daneben stabilisiert Rust 1.45 einige Library-APIs. Weitere Details zum Release lassen sich dem Rust-Blog entnehmen [4]. Die komplette Liste der Neuerungen und Bugfixes findet sich in den Release Notes [5].

(rme [6])


URL dieses Artikels:
https://www.heise.de/-4846103

Links in diesem Artikel:
[1] https://github.com/rust-lang/rust/issues/10184
[2] https://www.heise.de/news/Programmiersprache-Rust-1-30-will-mehr-Klarheit-schaffen-4204893.html
[3] https://rocket.rs/
[4] https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html
[5] https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1450-2020-07-16
[6] mailto:rme@ix.de