Kategorien
Featured-Post-Software-DE Software Engineering (DE)

Programmiersprachen für sicherheitskritische Systeme: Auswahl zwischen C, C++ und ihren sicheren Varianten

Auteur n°14 – Guillaume

Von Guillaume Girard
Ansichten: 4

Zusammenfassung – Die Abwägung zwischen C und C++ beeinflusst direkt Zertifizierung, Rückverfolgbarkeit, Wartbarkeit und Risiko sicherheitskritischer Systeme und bringt Low-Level-Kontrolle, Abstraktion sowie Compliance in Einklang. C punktet mit minimalem Binär-Footprint und unvergleichlicher Vorhersehbarkeit dank eines MISRA-Subsets und statischer Analysetools, während restriktiertes C++ die Strukturierung mit RAII und Smart Pointern in einem zertifizierbaren Subset modernisiert und von CI/CD-Pipelines sowie formellen Reviews profitiert.
Lösung: Etablierung einer ausgereiften DevSecOps-Governance und eines modularen Hybrid-Ökosystems mit eingefrorenen Schnittstellen, um Determinismus und Agilität ohne Kompromisse bei der Sicherheit zu vereinen.

Im Bereich der Entwicklung sicherheitskritischer Embedded-Systeme geht die technische Debatte um C und C++ weit über eine bloße Sprachpräferenz hinaus. Es handelt sich um eine entscheidende Architekturentscheidung, die Zertifizierung, Rückverfolgbarkeit, Wartbarkeit und das Gesamtrisiko des Produkts bestimmt.

Die Normen IEC 61508, ISO 26262 und die MISRA-Empfehlungen erlauben C und C++ nur in strikt definierten Subsets, unterstützt durch qualifizierte Werkzeuge und eiserne Disziplin. Die eigentliche Herausforderung besteht darin, Low-Level-Kontrolle, Abstraktion, Komplexität, Testbarkeit und Konformität auszubalancieren und gleichzeitig ein reifes DevSecOps-Ökosystem aufzubauen. Dieser Artikel beleuchtet diese Kompromisse und schlägt einen pragmatischen Ansatz vor, um extreme Robustheit mit geschäftlicher Agilität zu verbinden.

Vorteile von C in sicherheitskritischen Systemen

C ist der unangefochtene Meister in Speicherkontrolle und Vorhersagbarkeit. Seine konzeptionelle Schlichtheit und minimale Binärgröße machen es zur idealen Wahl für SIL 3/SIL 4.

Die Entscheidung für C in einem SIL 3- oder SIL 4-Kontext garantiert deterministisches Verhalten und direkten Zugriff auf die Speicherverwaltung. Diese Transparenz ermöglicht eine präzise Messung der Code- und Datensegmentgrößen, ein zentrales Kriterium für Zertifizierungs-Audits.

Durch die Einführung strenger MISRA-C-Regeln und den Einsatz qualifizierter statischer Analysewerkzeuge lassen sich die fehlenden Sprachkontrollen ausgleichen. Dies ist eine methodische Investition, die sich spürbar auf den Projektaufwand und die erforderlichen Kompetenzen auswirkt.

In einem Eisenbahnprojekt wählte ein Team ein C-Subset in Kombination mit einer zertifizierten Toolchain. Dies zeigte, dass ein rigider Prozess und systematische Code-Reviews die spät entdeckten Fehler um 70 % reduzieren und das externe Audit reibungsloser gestalten können.

Deterministischer Hardwarezugriff

Mit C lässt sich ein exaktes Mapping zwischen Ein-/Ausgangsregistern und Software-Datenstrukturen realisieren. Jeder Zugriff ist in CPU-Zyklen und Zeitmessung vorhersehbar, eine Grundvoraussetzung für Analysen der Worst-Case-Ausführungszeit (WCET).

Entwickler können manuell das Struktur-Alignment und die Cache-Optimierung steuern, was in höher abstrahierten Sprachen nicht immer möglich ist.

Diese Freiheit erfordert jedoch erhöhte Strenge im Umgang mit Zeigern, der Vermeidung von Buffer Overflows und dem Verzicht auf Ausnahmen, was ein quasi-mathematisches Formalismusniveau voraussetzt.

MISRA-Disziplin und statische Analyse

Die Anwendung der MISRA-C-Regeln zwingt zu einem stark eingeschränkten Sprach-Subset. Unsichere Konversionen, unkontrollierte Endlosschleifen oder die Verwendung untypisierter void-Zeiger sind ausgeschlossen.

Qualifizierte statische Analysewerkzeuge erkennen Regelverstöße automatisch und antizipieren undefiniertes Verhalten. Sie erstellen Berichte, die die Rückverfolgbarkeit für Zertifizierungsunterlagen wesentlich bereichern.

Der durch diese systematischen Verifikationsphasen entstehende Mehraufwand verlängert die Lieferzeiten, garantiert jedoch die für sicherheitskritische Systeme geforderte Robustheit.

Wartung und Know-how-Transfer

Der C-Code bleibt durch seine Schlichtheit auch über lange Zeiträume lesbar. Neue Ingenieure lassen sich leichter einarbeiten, da die konzeptionelle Granularität im Vergleich zu objektorientierten Sprachen begrenzt ist.

Gleichzeitig zwingt die strikte Befolgung interner Codier-Leitlinien und die lückenlose Dokumentation jedes Moduls schließlich zu einer technischen Schuld, wenn die Governance nicht kontinuierlich gepflegt wird.

Die Resilienz eines C-Projekts hängt daher ebenso sehr von methodischer Strenge wie von technischen Fähigkeiten ab, was die Bedeutung kontinuierlicher Weiterbildung unterstreicht.

Beitrag von C++ zur funktionalen Sicherheit

C++ bietet moderne Strukturierung und mindert bestimmte Risiken. Seine Abstraktionen verbessern die Kapselung, doch seine nicht-deterministischen Features sind oft verboten.

C++ bringt RAII, typisierte Container und Kapselung, was manuelle Speicherverwaltungsfehler reduziert und die Zuverlässigkeit des Business-Codes stärkt. Diese Vorteile steigern Produktivität und Wiederverwendbarkeit.

Ausnahmen, dynamische Speicherallokation, komplexe Templates und Polymorphismus werden in zertifizierten Projekten genau geprüft, quantifiziert oder schlicht untersagt. Häufig entsteht so ein hausinternes Subset, das einem „cleanen“ C++03 sehr nahekommt.

In einem Medizinprojekt entwickelte das Team ein restriktiertes C++-Subset, das von der Zertifizierungsstelle validiert wurde. Dies bewies, dass modulare Strukturierung und strikte Konformität mit einem sehr präzisen internen Codier-Leitfaden einhergehen können.

RAII und Speichersicherheit

Das RAII-Prinzip (Resource Acquisition Is Initialization) automatisiert die Freigabe von Ressourcen und verhindert zahlreiche Leaks. Smart Pointers minimieren das Risiko von Doppel-Frees oder Zugriffen auf bereits freigegebenen Speicher.

Standardcontainer wie std::vector eliminieren manuelle Pufferverwaltung, reduzieren die Fehleranfälligkeit und machen den Code ausdrucksstärker und kompakter.

Dafür kann die durch Templates erzeugte Codegröße ohne kontrollierte Strip- und Link-Phase deutlich ansteigen.

Komplexität von Templates und Polymorphismus

Templates bieten mächtige Generizität, sind jedoch aufwendig und für Zertifizierungen schwer analysierbar. Spezielle MISRA-C++-Regeln regeln ihren Einsatz.

Polymorphismus über virtuelle Vererbung oder abstrakte Schnittstellen erzeugt dynamische Dispatch-Tabellen, die statische Analysen und deterministische Garantien für ein kritisches System erschweren.

Um dem entgegenzuwirken, begrenzen einige Teams die Vererbung auf eine Ebene oder nutzen Alternativen wie CRTP (Curiously Recurring Template Pattern), um die Performance zu erhalten.

Unit-Tests und formale Reviews

Für C++ ist Testabdeckung essenziell, um RAII-Aufbau-/Abbau-Sequenzen und Ausnahme-Szenarien zu validieren. Leichte Frameworks werden bevorzugt, um das Laufzeitsystem nicht zu belasten.

Formale Reviews bauen auf Checklisten auf, die Templates, dynamische Allokationen und Subset-Konformität abdecken. Sie werden oft durch Inspektionen der Fehlerpfade ergänzt.

Die Integration dieser Phasen in eine kontrollierte CI/CD-Pipeline stärkt die Rückverfolgbarkeit und ermöglicht Auditoren den Nachweis der Subset-Beherrschung.

Edana: Strategischer Digitalpartner in der Schweiz

Wir begleiten Unternehmen und Organisationen bei ihrer digitalen Transformation.

DevSecOps-Grundpfeiler für sicherheitskritische Systeme

Governance und DevSecOps-Kultur sind der strategische Dreh- und Angelpunkt. Die Beherrschung eines zertifizierbaren Subsets hängt mehr vom Prozess als von der Sprachwahl ab.

Jenseits der Sprache bestimmt die DevSecOps-Reife den Erfolg von statischer Analyse, reproduzierbaren Builds und automatisierten Tests in einer kontrollierten CI/CD-Pipeline. Dies beruhigt Zertifizierungsstellen.

Die Governance umfasst Codier-Leitfäden, das Review technischer Schulden und Versionierung. Sie sichert einen rückverfolgbaren Verlauf für jedes eingebettete Modul.

Ein großes Energieunternehmen nutzt diesen Ansatz, um parallele Entwicklungen in C und C++ zu steuern. Dies beweist, dass nahtlose Integration zwischen Sprachteams und gemeinsame Governance der Schlüssel zur kontinuierlichen Konformität ist.

CI/CD-Integration und reproduzierbare Builds

Automatisierte Pipelines kompilieren und testen jeden Commit in einer geschützten Umgebung mit zertifizierten Compiler-Versionen. So werden Abweichungen zwischen Entwicklung und Produktion minimiert.

Durch feste Abhängigkeitsversionen und den Einsatz von Containern oder dedizierten VMs entstehen identische Binärartefakte.

Dieses Kontrollniveau in Verbindung mit integrierten statischen Analyseberichten bildet einen unverzichtbaren Nachweis der Strenge für Audits sicherheitskritischer Systeme.

Code-Reviews und technische Schuldverwaltung

Wöchentliche formale Reviews bewerten Abweichungen von MISRA-Vorgaben, ungetesteten Codeanteil und festgelegte Schnittstellendefinitionen.

Die Rückverfolgbarkeit von Tickets zu Verstößen gegen Coding Rules ermöglicht die Bewertung der technischen Schuld und die Priorisierung von Korrekturen nach erforderlichem Sicherheitsniveau (SIL 2 bis SIL 4).

Dies schafft einen positiven Kreislauf, in dem das Team Risiken antizipiert, schnell korrigiert und die Akkumulation von Altlasten vermeidet, die eine Zertifizierung verzögern könnten.

Schulung und Cross-Fertilization

Teams erhalten Schulungsprogramme zu C- und C++-Subsets, statischen Analysewerkzeugen und Unit-Test-Methodiken.

Gemischte Tandems aus C- und C++-Experten fördern den Erfahrungsaustausch und verhindern Sprachsilos.

Am Ende wird die DevSecOps-Kultur zum differenzierenden Faktor, der zugleich Agilität und Robustheit sicherstellt.

Hybrider Ansatz mit C und C++

C für die deterministischen Schichten und C++ für Abstraktionen. Modularität, gefrorene Schnittstellen und kontinuierliche Kontrollen sind pragmatische Hebel.

Ein hybrides Ökosystem kombiniert C für Echtzeittreiber und C++ für höherstufige Applikationsservices. Diese Koexistenz erfordert klare Grenzen und stabile Schnittstellen zwischen den Modulen.

Die Codier-Leitfäden definieren erlaubte Patterns für das Interfacing, während Code-Generatoren die Erstellung von Bindings automatisieren, um Kohärenz sicherzustellen.

In einem IoT-Projekt ermöglichte dieser Ansatz die Modernisierung einer bestehenden Firmware durch Hinzufügen von C++-Services, ohne die SIL 3-Zertifizierung zu gefährden. So wurden Agilität und Konformität zugleich unter Beweis gestellt.

Modulare Architektur und Entkopplung

Echtzeitfunktionen sind in C-Modulen isoliert, die getrennt als Binärdateien kompiliert werden, mit strikten Linker-Skripten. Applikationsservices liegen in C++-Bibliotheken, die nachträglich verlinkt werden.

IPC-Mechanismen (Interprozesskommunikation) oder generierte Stubs gewährleisten die Integrität der Kommunikation und erlauben Versionierung der Schnittstellen. Diese modulare Architektur stärkt die Kohärenz.

Diese Trennung erleichtert unit- und systembezogene Tests, da jedes Modul unabhängig in einer Testumgebung simuliert werden kann.

Gefrorene Schnittstellen und Versionsmanagement

Schnittstellen-Header werden eingefroren: Änderungen durchlaufen einen formalen Review- und Qualifikationsprozess. Frühere Versionen bleiben für die Abwärtskompatibilität erhalten.

Versionierungstools integrieren sich in die CI-Pipeline, um jede Release zu taggen und automatisch die zugehörige API-Dokumentation zu generieren, was die Rückverfolgbarkeit verbessert.

So stellen Teams sicher, dass funktionale Erweiterungen keine Brüche erzeugen – ein kritischer Faktor für langfristige Wartbarkeit.

Abdeckungskontrolle und kontinuierliche Audits

Codeabdeckungsziele (zum Beispiel 90 % für C und 80 % für C++) werden festgelegt. Berichte werden automatisch ausgewertet und für jeden Sprint konsolidiert.

Geplante externe Audits stützen sich auf diese Kennzahlen und statische Analyseprotokolle, wodurch die Vorbereitung der Zertifizierungsunterlagen verkürzt wird.

Diese kontinuierliche Kontrolle schafft eine bewährte Qualität und Konformität, selbst bei kontinuierlicher Auslieferung.

Optimieren Sie Robustheit und Agilität sicherheitskritischer Systeme

Die Wahl zwischen C, C++ oder ihren sicheren Varianten ist keine Frage der Sprachpräferenz, sondern ein Kompromiss zwischen Low-Level-Kontrolle, Abstraktion und Konformität. C punktet mit minimaler Binärgröße und Vorhersagbarkeit, vorausgesetzt, es wird eine MISRA-Disziplin und qualifiziertes Werkzeuging implementiert. C++ modernisiert die Strukturierung und verringert bestimmte Speicherfehler, erfordert jedoch ein restriktiertes Subset und kontrollierte Codegenerierung.

Der wahre Gewinn liegt in einer reifen DevSecOps-Governance: CI/CD-Pipelines, reproduzierbare Builds, formale Reviews und eine Kultur der Rückverfolgbarkeit. Ein hybrider Ansatz mit modularer Trennung und gefrorenen Schnittstellen vereint oft Determinismus und Flexibilität, ohne die funktionale Sicherheit zu gefährden.

Unsere Experten stehen Ihnen zur Verfügung, um gemeinsam mit Ihnen eine Strategie zu entwickeln, die Ihren Anforderungen an Sicherheit, Wartbarkeit und Innovation optimal gerecht wird.

Besprechen Sie Ihre Herausforderungen mit einem Edana-Experten

Von Guillaume

Softwareingenieur

VERÖFFENTLICHT VON

Guillaume Girard

Avatar de Guillaume Girard

Guillaume Girard ist Senior Softwareingenieur. Er entwirft und entwickelt maßgeschneiderte Business-Lösungen (SaaS, Mobile Apps, Websites) und komplette digitale Ökosysteme. Mit seiner Expertise in Architektur und Performance verwandelt er Ihre Anforderungen in robuste, skalierbare Plattformen, die Ihre digitale Transformation unterstützen.

FAQ

Häufig gestellte Fragen zu C und C++ für sicherheitskritische Systeme

Wann sollte man für ein SIL3- oder SIL4-kritisches Projekt reines C bevorzugen?

Reines C in einem SIL3-/SIL4-Kontext gewährleistet deterministisches Verhalten und eine minimale Binärgröße. Direkte Speicherverwaltung und hardwarenahe Zugriffe erleichtern die WCET-Analyse. Diese Entscheidung erfordert jedoch die strikte Anwendung eines MISRA-C-Subsets, den Einsatz zertifizierter statischer Analysetools sowie eine konsequente Entwicklungsmethodik, um fehlende Sprachsicherheiten auszugleichen.

Was sind die Hauptherausforderungen eines MISRA-C-Subsets?

Das MISRA-C-Subset schränkt die Verwendung ungetypeter Zeiger, unkontrollierter Endlosschleifen und impliziter Typumwandlungen stark ein. Zertifizierte statische Analysen erkennen Verstöße und erstellen Rückverfolgbarkeitsberichte, die für die IEC 61508- oder ISO 26262-Zertifizierung unverzichtbar sind. Diese Strenge erhöht den Projektaufwand und verlängert den Lieferzyklus, garantiert aber die nötige Robustheit für sicherheitskritische Systeme.

Wie kann C++ trotz seiner Einschränkungen die funktionale Sicherheit stärken?

Durch RAII und Smart Pointers verbessert C++ das Ressourcenmanagement und reduziert Speicherlecks. Typisierte Templates und Container erhöhen Ausdruckskraft und Wiederverwendbarkeit des Anwendungscodes. In Zertifizierungsprojekten nutzt man häufig ein abgespecktes C++2003-Subset, verzichtet auf unkontrollierte Ausnahmen und dynamische Speicherallokation und legt eine interne Coding-Policy zugrunde, um Modularität und strikte Konformität zu vereinen.

Wie lässt sich die Codeerzeugung und Binärgröße in C++ kontrollieren?

Die C++-Codegenerierung kann durch Template-Instanziierungen die Binärgröße aufblähen. Um dem entgegenzuwirken, setzt man Stripping-Tools, kontrollierte Linkerskripte und Compiler-Direktiven zur Drosselung übermäßiger Optimierungen ein. Der Einsatz leichter Patterns und eines restriktiven C++-Subsets gewährleistet eine vorhersagbare Binärgröße, was für Zertifizierungsaudits essenziell ist.

Welche hybride Architektur verbindet C für Echtzeitanforderungen und C++ für die Anwendungslogik?

Eine hybride Architektur trennt die deterministischen Ebenen (Treiber und ISR) in C-Module, die in dedizierte Binärdateien kompiliert werden, während Anwendungskomponenten in C++-Bibliotheken nachträglich gelinkt werden. Gefrorene Schnittstellen und IPC-Mechanismen oder generierte Stubs sichern den Datenaustausch und erleichtern die evolutionäre Wartung, ohne die SIL3-Zertifizierung zu gefährden.

Welche Indikatoren gilt es in einer DevSecOps-Pipeline für sicherheitskritische Systeme im Blick zu behalten?

In einer DevSecOps-Pipeline für sicherheitskritische Systeme sind Testabdeckung (≥ 90 % bei C, ≥ 80 % bei C++), MISRA-Regelverstöße und Build-Reproduzierbarkeit wesentliche Kennzahlen. Statische Analyseberichte und Versionslogs ermöglichen Rückverfolgbarkeit, verringern Diskrepanzen zwischen Entwicklung und Produktion und schaffen Vertrauen bei Auditoren.

Wie kann man technische Schulden, die durch Coding-Regeln entstehen, in einem zertifizierten Umfeld steuern?

Technische Schulden werden durch wöchentliche formelle Reviews, Rückverfolgbarkeit von Non-Konformitäts-Tickets und Priorisierung von Korrekturen nach Sicherheitslevel (SIL2 bis SIL4) gesteuert. Definierte Schwellenwerte für Testabdeckung und Regelverstöße im internen Coding-Guide helfen, Risiken früh zu erkennen und eine Ansammlung von Schulden zu vermeiden, die die Zertifizierung verzögern könnte.

Welche Stolperfallen sollte man bei der Verwendung von Templates und Polymorphismus in zertifiziertem C++ umgehen?

In zertifiziertem C++ beschränkt man Vererbung auf eine Ebene und vermeidet komplexe Metaprogrammierungs-Templates, die statische Analysen erschweren. Das CRTP (Curiously Recurring Template Pattern) ermöglicht Performance-optimierten Dispatch. Dynamisches Polymorphismus und unkontrollierte Speicherallokationen sind streng zu reglementieren, um deterministisches Verhalten sicherzustellen.

KONTAKTIERE UNS

Sprechen Wir Über Sie

Ein paar Zeilen genügen, um ein Gespräch zu beginnen! Schreiben Sie uns und einer unserer Spezialisten wird sich innerhalb von 24 Stunden bei Ihnen melden.

ABONNIEREN SIE

Verpassen Sie nicht die Tipps unserer Strategen

Erhalten Sie unsere Einsichten, die neuesten digitalen Strategien und Best Practices in den Bereichen Marketing, Wachstum, Innovation, Technologie und Branding.

Wir verwandeln Ihre Herausforderungen in Chancen

Mit Sitz in Genf entwickelt Edana maßgeschneiderte digitale Lösungen für Unternehmen und Organisationen, die ihre Wettbewerbsfähigkeit steigern möchten.

Wir verbinden Strategie, Beratung und technologische Exzellenz, um die Geschäftsprozesse Ihres Unternehmens, das Kundenerlebnis und Ihre Leistungsfähigkeit zu transformieren.

Sprechen wir über Ihre strategischen Herausforderungen.

022 596 73 70

Agence Digitale Edana sur LinkedInAgence Digitale Edana sur InstagramAgence Digitale Edana sur Facebook