C++ vs Rust

Modernes C++ und Rust: Wenn Theorie auf Praxis trifft

Modernes C++ oder Rust? Erfahren Sie, wie sich beide Sprachen in der Praxis unterscheiden – von Legacy-Herausforderungen bis zu modernem Tooling – und welche Option zu Ihrer Codebase passt.

Modernes C++ versucht, bezüglich Sprachfeatures relevant zu bleiben und rüstet nach. C++20 und C++23 bringen zum Beispiel Concepts, Ranges und den Spaceship-Operator. Auf dem Papier sind diese Konstrukte durchaus konkurrenzfähig. In der Praxis zeigen sich aber die Grenzen dieser Kompatibilität. 

Die C++-Realität in der Praxis

Alltägliche Entwicklungsaufgaben zeigen den Unterschied deutlich. Projektsetup mit CMake, Dependency-Management oder die Implementierung von Enums mit zugehörigen Daten: Was in Rust native Sprachkonstrukte sind, erfordert in C++ erheblichen Zusatzaufwand und grosses Verständnis der Sprache.

Ein konkretes Beispiel aus unserem technischen Vergleich: Enums, die Daten enthalten können (algebraic data types). In Rust schreibt man:

enum Command {
    Stop,
    MoveTo { x: f64, y: f64, z: f64 },
    Grip { force: f64 },
}

In C++ braucht es std::variant, separate Strukturen für jede Variante und ein overloaded Helper-Template, um ähnliche Funktionalität zu erreichen.

Die historische Kompatibilität zu C und die Rückwärtskompatibilität haben ihren Wert, aber auch ihren Preis. Beispielsweise Move-Semantik kam als nachträgliche Ergänzung über das komplizierte Konzept der rvalue-references. Und man muss sich erst noch mit «moved from»-Objekten herumschlagen (die umständlich gerechtfertigt werden aber im Effekt einfach kaputt sind). In Rust wird einfach die Ownership verschoben und der Compiler verhindert, dass man auf den ehemaligen Owner zugreift. Radikale aber nützliche Sprachverbesserungen bleiben dadurch oft aussen vor. 

bbv Techblog Rust vs. C++

Rust vs modern C++

Rust trifft auf modernes C++: Ein fairer Vergleich einiger Sprachfeatures aus technologischer Sicht. Jetzt lesen auf Tech Insights – der bbv Blog von Techies für Techies.

Das Legacy-Problem

Typische Unternehmens-Codebases zeigen das Dilemma: C++98-Patterns neben modernem C++20-Code im selben Projekt. Eine vollständige Modernisierung würde bedeuten, die gesamte Basis anzufassen. Dies kommt wirtschaftlich einer Neuentwicklung nahe. Selbst wenn der Compiler C++20 beherrscht, nutzt der Code es nicht zwingend.

Linter und statische Codeanalyse wie clang-tidy helfen, müssen aber erst eingerichtet und konfiguriert werden. In Legacy-Projekten bedeutet das: Hunderte bestehende Warnungen beheben, bevor man produktiv wird. Fairerweise muss man sagen, dass es dieses Problem immer gibt, wenn die Codebasis vernachlässigt wird. 

C++ ist mächtig, aber kompliziert und komplex

Die Mächtigkeit von C++ hat eine Kehrseite. Entwickler bleiben oft beim Vertrauten, statt moderne Features zu nutzen, weil die Lernkurve steil ist. Neue Teammitglieder stehen vor der Herausforderung, sowohl historische als auch aktuelle Idiome zu beherrschen, um die gesamte Codebase zu verstehen und weiterzuentwickeln.

Rust: Neuanfang

Rust ist 30 Jahre jünger und konnte Erkenntnisse aus Jahrzehnten Programmiersprachenentwicklung einfliessen lassen. Rust musste auch keine Kompromisse eingehen, um mit einer Basissprache kompatibel zu sein. Die Sprache wurde aufgrund von heutigen Anforderungen designed. Die Kompromisse wurden so gewählt, dass die Sprache modernen Anforderungen genügt. Vererbung gibt es zum Beispiel gar nicht in Rust. In den allermeisten Fällen ist das gut (favour composition over inheritance), in Spezialfällen wäre es aber nützlich. Ein anderes Beispiel dafür ist die Orphan Rule (Trait Coherence): Man kann nicht fremde Traits für fremde Typen implementieren. Das stört, weil man das eben möchte, um Komponenten lose zu koppeln. Andererseits birgt die Software so weniger böse Überraschungen, weil nicht irgendwo irgendwas implementiert wird.

Header Blogserie Rust Integration ins Team.

Erfolgreiche Einführung von Rust in Ihrem Team

Wie schaffen Sie es, Rust in Ihr bestehendes Team einzuführen? Essenziell dafür sind motivierte Mitarbeitende, eine klare Roadmap und die Weitergabe von Wissen.

Durchdachte Sprachkonzepte

Pattern Matching, Slices und algebraische Typen sind von Anfang an eingebaut, nicht nachgerüstet. Der Borrow Checker, algebraische Datentypen und Result-Types erzwingen durchdachtes Design bereits zur Compile-Zeit. Was der Compiler durchlässt, ist zwar nicht zwingend frei von Logikfehlern, läuft aber in der Regel auf dem Target.

Tooling als Kernbestandteil

Salopp gesagt ist Cargo das CMake für Rust. Es vereint Package-Management, Build-System, Testing und Dokumentation in einem Werkzeug. Formatter (rustfmt) und Linter (clippy) sind im Handumdrehen integriert. Das Ökosystem bietet integrierte Lösungen für Security-Audits (cargo-audit), Dependency-Analysen (cargo-tree) und weitere Qualitäts-Checks. Cargo ist intuitiv begreifbar und entdeckbar. Im Gegensatz zu CMake, was am Anfang eine steile Lernkurve abverlangt.

Keine Entweder-Oder-Entscheidung

C++ modernisieren ist bei bestehenden Codebases und eingespielten Teams eine valide Option. Rust bietet bei Neuentwicklungen klare Vorteile durch kohärentes Design und modernes Tooling. Auch Hybrid-Ansätze funktionieren: Rust-Module lassen sich über Foreign Function Interfaces in C++-Projekten integrieren.

Die zentrale Frage ist nicht «Was ist im Allgemeinen besser?», sondern «Was passt zu Ihrer spezifischen Situation?», also zu Ihrer Codebase, Ihrem Team, Ihren Projekt-Anforderungen.

Expertise in beiden Welten

bbv verfügt über fundierte Erfahrung sowohl in modernem C++ als auch in Rust. Wir kennen die Stärken und Schwächen beider Ansätze aus der Praxis. Unser Service ist technologieneutral und orientiert sich an Ihrer konkreten Ausgangslage.

FAQ

Rust eignet sich besonders für Neuentwicklungen, bei denen kohärentes Sprachdesign und modernes Tooling von Anfang an verfügbar sein sollen. C++ bleibt sinnvoll, wenn Entwickler und Codebase modernes C++ bereits beherrschen und eine Migration wirtschaftlich nicht zu rechtfertigen ist. Performance ist dabei kein Differenzierungsmerkmal: Rust und C++ sind diesbezüglich nahezu gleichwertig. Rust bietet jedoch strukturelle Vorteile bei Memory Safety und Wartbarkeit: Der Borrow Checker verhindert ganze Klassen von Speicherfehlern zur Compile-Zeit, und das integrierte Tooling reduziert den Aufwand für Qualitätssicherung gegenüber C++ deutlich.

Entwickler bleiben oft beim Vertrauten, statt moderne Features zu nutzen, weil die Lernkurve für modernes C++ steil ist. Neue Teammitglieder müssen sowohl historische als auch aktuelle Idiome beherrschen, um die gesamte Codebase zu verstehen und weiterzuentwickeln. Selbst wenn der Compiler C++20 unterstützt, zieht der bestehende Code nicht automatisch nach. Werkzeuge wie clang-tidy helfen bei der Qualitätssicherung, müssen aber erst eingerichtet werden und erzeugen in Legacy-Projekten zunächst eine grosse Menge an Warnungen.

Technisch ist das problemlos möglich: Rust-Module lassen sich über Foreign Function Interfaces in bestehende C++-Projekte integrieren. Ein hybrider Ansatz ist aber eher eine pragmatische Zwischenlösung als ein Zielzustand, etwa wenn eine vollständige Migration wirtschaftlich nicht realistisch ist. Ob er sinnvoll ist, hängt von der konkreten Codebase, dem Team und den Projektanforderungen ab.

Portrait Oliver With
Der Experte

Oliver With

Oliver With ist Spezialist für Embedded Software. Als Senior-Entwickler ist er überzeugt, dass eng zusammenarbeitende Teams komplexe Probleme am besten lösen. Kreativität in der Lösungsfindung vereint er mit Qualität in der Entwicklung, um erfolgreiche Produkte zu schaffen. Er ist Rust-Enthusiast, weil es mit Rust erstmals eine Sprache gibt, die Sicherheit, Performance, Akzeptanz in der Industrie und Ergonomie für Entwickler kombiniert.
Senior Software-Ingenieur Embedded

Unser Wissen im Abo

Attention!

Sorry, so far we got only content in English for this section.