7 Punkte von GN⁺ 2025-05-07 | 4 Kommentare | Auf WhatsApp teilen
  • Der Autor, der seit mehr als 20 Jahren C++ nutzt, schildert anhand eines Vortrags von Matt Godbolt, was ihn dazu brachte, die Stärken von Rust neu zu entdecken
  • In C++ werden Fehler durch Typverwechslungen vom Compiler oft nicht zuverlässig erkannt, während Rust sie zur Compile-Zeit konsequent verhindert
  • Rust ist nicht nur bei der Speichersicherheit stark, sondern auch so entworfen, dass Missbrauch von APIs erschwert wird
  • Besonders bei der Verarbeitung von Laufzeiteingaben zwingt Rust dazu, Fehler explizit zu behandeln, was Risiken reduziert
  • Am Ende zeigt sich, dass Sprachdesign ein mächtiges Werkzeug sein kann, um Entwicklerfehler zu verhindern

Einleitung

  • Matt Godbolts Vortrag "Correct by Construction" beleuchtet Probleme im API-Design von C++ und passt damit gut zur Philosophie von Rust
  • Der Vortrag ist ein guter Einstieg, um die Stärken von Rust zu verstehen

What's in a type — die Grenzen von C++

  • Eine Funktionssignatur wie void sendOrder(const char *symbol, bool buy, int quantity, double price) ist sehr fehleranfällig
  • Wenn nur Grundtypen wie bool, int und double verwendet werden, warnt der Compiler nicht, selbst wenn Typen vertauscht werden
  • Typ-Aliasse wie using Price = double bieten keine echte Typtrennung
  • Erst mit Klassen und explicit-Konstruktoren für Quantity und Price kann der Compiler einige Fehler erkennen, aber:
    • Negative Werte sind weiterhin erlaubt, und das wird erst zur Laufzeit zum Problem
    • Mit static_assert und Templates lassen sich Compile-Time-Prüfungen erzwingen
    • Trotzdem können Laufzeitkonvertierungen wie atoi weiterhin Integer-Überläufe verursachen, ohne dass der Compiler sie erkennt

Was macht Rust anders?

  • Selbst bei derselben Funktionsdefinition meldet Rust Typinkompatibilitäten eindeutig bereits beim Kompilieren als Fehler
  • Neue Typdefinitionen wie struct Price(pub f64); struct Quantity(pub u64); sind ebenfalls einfach, und negative Eingaben werden ganz natürlich abgefangen
  • Bei Laufzeit-Stringkonvertierungen wie "string".parse::<u64>() ist explizite Fehlerbehandlung erforderlich
  • Wenn man mit .expect() das Unwrapping eines Werts erzwingt, kommt es zwar zu einem Laufzeitabsturz, doch das ist laut Text immer noch besser als stille Fehler in C++

Fazit

  • Rust schützt Entwickler weit über reine Speichersicherheit hinaus durch Verhinderung von API-Missbrauch, Compile-Time-Prüfungen und ein klares Typsystem
  • Das zeigt, dass die Kraft des Sprachdesigns Entwicklerfehler schon im Vorfeld verhindern kann
  • Rust-Einsteiger können zunächst damit kämpfen, sich mit dem Borrow Checker auseinanderzusetzen, doch das legt sich mit der Zeit
  • C++ hat sich historisch stark weiterentwickelt, doch es zeigt sich weiterhin, dass es nur schwer dieselbe grundlegende Sicherheit und Klarheit wie Rust bieten kann

Referenz

4 Kommentare

 
cronex 2025-05-08

Die meisten Punkte, die als Nachteile von C++ angeführt werden, scheinen größtenteils Inhalte zu sein, die wegen der Kompatibilität mit C beibehalten werden. Lässt sich C-Kompatibilität aufgeben und die Sprache so ändern, dass man damit entwickeln kann?

 
coremaker 2025-05-08

Es wäre besser gewesen, wenn unsafe nicht bereitgestellt worden wäre.

 
codemasterkimc 2025-05-08

Die grundlegende Sprache = Rust

 
GN⁺ 2025-05-07
Hacker-News-Kommentare
  • Der größte Vorteil von Rust ist die vereinheitlichte Fehlerweitergabe über den einheitlichen Typ Result. Es ist attraktiv, dass man sich nicht um Ausnahmebehandlung oder verschiedene Arten der Fehlerrückgabe kümmern muss.

    • Dank der ?-Kurzschreibweise und der funktionalen Schnittstelle von Result macht Fehlerbehandlung Spaß und ist leicht zu handhaben.
    • Im Vergleich zur komplexen Fehlerbehandlung in C++ stört die mangelnde Konsistenz.
  • Es gibt viel Unzufriedenheit mit C++. Besonders problematisch ist, dass man sich viele Regeln merken muss und der Code schon bei einem einzigen Fehler anfällig werden kann.

    • Um die Sicherheit von C++ zu erhöhen, braucht es einen Ansatz, der den sicheren Methoden von Rust ähnelt.
  • Der aktuell geschriebene C++-Code ähnelt Rust. Es werden explizite und starke Typen sowie eine klare Verwaltung der Lebensdauer verwendet.

    • Der Rust-Compiler hilft stärker dabei, Bugs zu finden und Fehler zu melden.
  • Das Problem impliziter Konvertierungen in C++ ist eher ein Bibliotheks- als ein Sprachproblem.

    • Auch in C++ lassen sich Rust-ähnliche Funktionen umsetzen, dafür braucht es aber Bibliotheksunterstützung.
  • In Rust ist es unpraktisch, Args-/Options-Structs zu verwenden, weil es keine Keyword-Argumente oder benannten Tupel gibt.

  • Die Option -Wconversion kann bestimmte Konvertierungsprobleme erkennen, gilt aber nicht für alle Fälle.

    • Zum Beispiel wird die Umwandlung von 1000.0 in 1000 nicht als Genauigkeitsverlust betrachtet.
  • Ein weiterer Vorteil von Rust ist, dass es keine impliziten numerischen Konvertierungen gibt. In C++ sollte man statt atoi besser die Konvertierungsfunktionen der STL verwenden.

  • Funktionen ähnlich wie SQL-Constraints oder benutzerdefinierte Typen und Validatoren von pydantic gibt es in Rust oder Golang bislang noch nicht.

  • Wer sich für den Programmier-Podcast „Two's Complement“ von Matt und Ben Rady interessiert, sollte einmal reinhören.