Veröffentlicht am: 24 Februar 2023
Experte:
Ir. Kris van Rens
Trainer
Lesen Sie mehr über Kris van Rens
Teilen

Trotz einer Vielzahl aufstrebender Alternativen ist C++ immer noch eine Macht, mit der man rechnen muss, vor allem in der von Altlasten geplagten High-Tech-Branche. In einer Reihe von Artikeln stellt der Trainer des High Tech Institute, Kris van Rens, die Sprache in eine moderne Perspektive. In unserem neuen 4-tägigen Trainingskurs führt Kris van Rens die Teilnehmer in die Grundlagen der Sprache und die wichtigsten Best Practices ein.

Alle paar Jahre werden C und C++ für tot erklärt. Kürzlich hat Mark Russinovich, CTO von Microsoft Azure, öffentlich erklärt, dass sie zugunsten von Rust veraltet sein sollten. Das ist zwar eine persönliche Äußerung, aber für jemanden von Microsoft, der über eine enorme C++-Codebasis und viele aktive Mitglieder im C++-Komitee verfügt, ist das eine interessante Meinung.

Unabhängig davon sind C und C++ immer noch sehr lebendig – beide sind die Lingua Franca vieler industrieller Softwareentwicklungsumgebungen. Und doch ist Rust derzeit der „Place to be“ im Land der Systemprogrammierung. Was ist es, das diese Sprache so attraktiv macht? Betrachten wir sie einmal aus der Perspektive von C++.

Bemerkenswerte Unterschiede

Zunächst einmal bietet Rust einen klaren und objektiven Vorteil gegenüber C++: garantierte Speichersicherheit für das kompilierte Ergebnis. Im Wesentlichen tauscht Rust die Kompilierungszeit (und die Komplexität des Compilers) gegen eine sicherere Laufzeit ein. Der Compiler wird versuchen, sich selbst davon zu überzeugen, dass der Code, den Sie ihm übergeben, speichersicherfähig ist. Dazu verwendet er sein Typsystem und manchmal auch die Hilfe des Entwicklers, um Dinge wie die Abhängigkeit von Variablen oder die Lebensdauer von Referenzen anzuzeigen.

Mehrere unabhängige Sicherheitsstudien zu großen C- und C++-Codebasen haben gezeigt, dass übereinstimmend satte 70 Prozent aller Bugs und Sicherheitsprobleme mit der Speichersicherheit zusammenhängen. In Anbetracht dessen scheint der Tausch von Kompilierzeit gegen eine speichersichere Laufzeit eine logische Schlussfolgerung zu sein. Wenn Sie qualitativ hochwertiges C++ mit den richtigen Tools, Tests, Best Practices und Compiler-Sanitizern schreiben, können Sie dieses Ziel auch erreichen, aber es gibt keine festen Garantien von Anfang an. Die ‚Leitplanken‘, die Rust implementiert, um Sie davor zu schützen, sich selbst in den Fuß zu schießen, mögen manchmal komplex oder sogar ärgerlich sein, aber denken Sie an die beträchtlichen Vorteile, die eine Garantie für die Speichersicherheit zur Laufzeit bei der Programmierung von nebenläufiger Software bietet.

''As software engineers, we should use the right tool for the job.''

Ein weiterer bemerkenswerter Unterschied zu C++ ist die Art und Weise, wie Rust die Behandlung von Fehlern und Funktionsergebniswerten integriert. Im Gegensatz zu C++ gibt es keine Ausnahmen. Rust bietet Mechanismen zur Behandlung von Fehlern über den normalen Kontrollfluss. Die Ergebniswerte müssen verarbeitet werden, so dass der Entwickler gezwungen ist, eine Fehlerbehandlung zu implementieren und fehlerhaften Code zu verhindern, so dass Fehler oder Ausnahmen nur selten unter dem Radar verschwinden. Wenn während der Laufzeit wirklich etwas schief läuft – z.B. wenn der Speicher erschöpft ist – erzeugt Rust eine so genannte Panik, einen fatalen Fehler, der den betreffenden Thread anhält (der anständig behandelt werden kann).

Der Rust-Compiler, der auf dem LLVM-Compiler-Backend aufbaut, ist offensichtlich sehr pedantisch, um die Speichersicherheit und die Korrektheit des Codes aufrechtzuerhalten, aber gleichzeitig auch sehr hilfreich. Betrachten Sie ihn als ein Paar Programmierer, das Ihnen über die Schulter schaut und lesbare Fehlermeldungen liefert und sogar mögliche Lösungen vorschlägt. Abgesehen vom Compiler dreht sich der größte Teil des Rust-Tooling-Ökosystems um Cargo, das ein Build-System, einen Paket- und Abhängigkeitsmanager und vieles mehr in einem ist. Trotz der Fülle an Paketmanagern, Build-Systemen und anderen Tools, die für C++ zur Verfügung stehen, kann das Einrichten eines ernsthaften C++-Projekts immer noch eine Qual sein.

Da Rust relativ jung ist, hatte es den Luxus, über 40 Jahre Sprachentwicklung in seine Syntax und Struktur einfließen zu lassen. Ein Großteil der Inspiration wurde sowohl von imperativen Sprachen wie C++ als auch von funktionalen Sprachen wie Haskell und Scheme übernommen. Das verleiht ihr den subjektiven Vorteil eines sehr ‚modernen‘ Gefühls. Außerdem sind viele Dinge in Rust Ausdrücke, die mehr Flexibilität in der Code-Notation bieten.

In meinem vorherigen Beitrag habe ich argumentiert, dass die Benutzerbasis einer Programmiersprache von größter Bedeutung ist. Mit Hilfe der Rust Foundation baut Rust diese Benutzerbasis allmählich auf, wie sich aus vielen Indikatoren wie dem Tiobe-Index und der Stack Overflow-Umfrage sowie der Aufnahme von Rust in den Linux-Kernel v6.1 ableiten lässt – keine geringe Leistung. Da immer mehr Sicherheitsberichte von positiven Effekten sprechen, die eng mit der Verwendung von speichersicheren Sprachen wie Rust zusammenhängen, wird die Benutzerbasis weiter wachsen. Jeder Hinweis (kein Wortspiel beabsichtigt) scheint auf eine glänzende Zukunft für Rust hinzuweisen.

Nicht nur Sonnenschein und Rosen

Sollten wir dann C und C++ zugunsten von Rust einfach verwerfen? Meiner Meinung nach stellt dies eine falsche Dichotomie dar. Warum sollten wir uns zwischen dem einen oder dem anderen entscheiden müssen? Als Software-Ingenieure sollten wir das richtige Werkzeug für die jeweilige Aufgabe verwenden.

Die Umstellung auf Rust ist auch nicht nur ein Zuckerschlecken. Wenn Sie einen großen Bestand an bestehendem C++-Code haben, ist Rust nicht direkt eine Hilfe, es sei denn, Sie sind bereit, für die Interaktion auf C-APIs zurückzugreifen. Es gibt Tools für die Interoperabilität auf C++-Ebene, aber diese stecken noch in den Kinderschuhen. Natürlich könnten Sie Ihren Code auch neu schreiben – aber das wird nicht einfach sein, vor allem nicht, wenn Sie sich stark auf erweiterte Vorlagen stützen. Und wenn Sie sich auf absolute Maximalanforderungen an die Leistung verlassen, ist Safe Rust dem vielleicht (noch?) nicht gewachsen. Außerdem schreiben Standards in strengeren Umgebungen wie der Automobil- oder Luftfahrtindustrie oft die Verwendung einer formal spezifizierten Programmiersprache vor, was Rust derzeit nicht ist.

Der beste Rat ist, sich nicht auf eine einzige Programmiersprache festzulegen. Das Erlernen mehrerer Sprachen ist im Allgemeinen sehr vorteilhaft und wird Ihre Kompetenz, Ihren Stil und Ihre Kenntnisse in jeder Sprache, die Sie beherrschen, verbessern. Werfen Sie also einen Blick auf C++, Rust und andere Alternativen, um Ihren Blickwinkel zu erweitern – oder einfach nur, um Spaß zu haben.

Das Training von Kris van Rens wird zweimal im Jahr angeboten.