C vs C++ – Mikrocontroller.net (2024)

Speziell bei der Verwendung höherer Programmiersprachen (HLLs) im Bereich der Programmierung von Mikrocontrollern taucht häufig die Frage auf, ob eine Sprache wie C++ für "kleinere" Mikroprozessoren nicht einen zu großen Overhead darstelle und ob man nicht besser bei C (oder gar Assembler) bleiben solle.

Inhaltsverzeichnis

  • 1 Beziehung zwischen C und C++
  • 2 C++-Performance-Fußangeln
    • 2.1 Fußangel-Beispiel 1
    • 2.2 Fußangel-Beispiel 2
  • 3 Vererbung und Aggregation
  • 4 Virtuelle Methoden
  • 5 Interfaces (Abstrakte Basisklassen)
  • 6 Exceptions (Ausnahmebehandlung)
  • 7 Laufzeit-Typinformation
  • 8 Templates (Schablonen)

Beziehung zwischen C und C++

Ursprünglich entstand C++ als Erweiterung zu C (mit minimalen Ausnahmen - Leitlinie: "As close to C as possible, but no closer"). Damit ist C als Teilmenge in C++ enthalten und jedes C-Programm ist zugleich ein C++-Programm, denn es kann auch mit einem C++-Compiler übersetzt werden (nicht aber umgekehrt!). Da ein weiterer Grundsatz bei der C++-Entwicklung lautete "You only pay for what you use", entsteht in einem Programm, das ausschließlich C-Features benutzt aber mit einem C++-Compiler übersetzt wird, kein prinzipiell bedingter Overhead.

So weit die Theorie.

Der Artikel wurde ursprünglich im Jahr 2004 verfasst. Einige der im weiteren Verlauf genannten Punkte, insbesondere bzgl. Optimierungen, Performance und unnötige Funktionsaufrufe, treffen auf aktuelle Compiler nicht mehr zu. Es gibt verschiedene (Web-basierte) Tools, um das Compiler-Ergebnis von C++ Code zu untersuchen:

  • Compiler Explorer (https://godbolt.org) - Hilft zu zeigen, wie der vom C++ Compiler erzeugte Assembler Code aussieht.
  • C++ Insights (https://cppinsights.io) - Hiermit lässt sich nachvollziehen, was ein C++ Konstrukt auf Code Ebene erzielt.

C++-Performance-Fußangeln

Allerdings waren die Zielsysteme bei der Weiterentwicklung von C++ in den letzten 20 Jahren in der Regel PCs und leistungsfähige Workstations, was in der Praxis zwei wichtige Konsequenzen hatte:

  • Die Sprachsyntax von C++ verschleiert mehr als die von C, womit man sich in einem Programm möglicherweise einen hohen, in der Programmierung von Mikrocontrollern unerwünschten Overhead ohne konkreten Nutzen einhandelt.
  • Die tatsächlichen Implementierungen von C++ bemühen sich weniger als die von C, ausführbare Programme (Executables) in der sparsamsten möglichen Form zu erzeugen.

Fußangel-Beispiel 1

Mitunter werden beim Einsatz von C++ Programmierrichtlinien angewendet, die im Bereich der Mikrocontrollern-Programmierung unsinnig sind oder zumindest nach anderen Kriterien bewertet werden müssen als im PC- und Workstation-Umfeld.So führen etwa "vorsorglich angelegte", aber leere Konstruktoren und Destruktoren in der Regel zu vielen Unterprogramm-Sprungbefehlen, an deren Ziel sofort wieder ein Rücksprung steht.

Oder es werden - dem Beispiel von Java oder bestimmten Entwurfsmustern folgend - Objekte in jedem Fall dynamisch angelegt, was das Einbinden komplexer Unterstützungsroutinen für die Speicherverwaltung auslöst und in keinem Fall zu Ergebnissen führt, deren Performance vergleichbar zu einfachen Variablen auf dem Stack oder an festen Adressen ist.

Fußangel-Beispiel 2

Manchmal wird ein einfaches "hello, world"-Programm in C und eines in C++ auf einem PC kompiliert und die Größe des erzeugten Executables als Kriterium für den Ressourcen-Bedarf der jeweiligen Programmiersprache herangezogen. Dieser Vergleich kann sehr in die Irre führen, da die typischen Ausgabe-Anweisungen der Sprachen C und C++ von Bibliotheksfunktionen abgewickelt werden, die aber mit Sicherheit bei der Kompilierung für einen Mikrocontroller ganz anders aussehen (wenn sie dort überhaupt vorhanden sind).

Bei der Strukturierung von unterstützenden Bibliotheksfunktionen wird im PC- und Workstationbereich kaum darauf geachtet, ob einem Minimal-Programm möglicherweise unnötiger Overhead mit hinzugebunden wird. So könnte beispielsweise - obwohl nur eine einfache Zeichenkette ausgegeben wird - durch eine Ausgabeanweisung die Unterstützung für die Ausgabe aller Datentypen inklusive Gleitpunktzahlen angesprochen werden, dies könnte wiederum das Hinzubinden der mathematischen Bibliothek auslösen und - bei Kompilierung für einen Prozessor ohne Hardware-Support für Gleitpunkt-Operationen - einer weiteren Bibliothek zu deren Emulation. Das alles, wie gesagt, obwohl überhaupt keine Gleitpunktzahl in der konkreten Ausgabe vorkommt.

Vererbung und Aggregation

Beide Mechanismen sind aus Sicht der Umsetzung als geschachtelte Strukturen zu verstehen. Eventuelle kleinere Performance-Einbußen könnten durch die fehlende Möglichkeit der Register-Optimierung entstehen, die ein Compiler bei mehreren, nicht zu einer Struktur zusammengefassten Variablen prinzipiell hat. Allerdings sind die Vor- und Nachteile hier in C und C++ die selben, und insofern ist das Thema für einen Vergleich "C vs. C++" nicht relevant.

In größeren Programmen überwiegt in aller Regel der Vorteil der besseren Strukturierung durch die Zusammenfassung von Einzelvariablen, insbesondere wenn auch die in C++ vorhandenen Mechanismen zum Zugriffsschutz eingesetzt werden. In kleinen Programmabschnitten mit extrem kritischer Performance kann ggf. eine "Hand-Optimierung" und Auflösung von Strukturen in Einzelvariablen erfolgen (oder gleich eine Re-Implementierung in Assembler).

Virtuelle Methoden

Virtuelle Methoden sind im Grunde genommen Funktionszeiger und insofern überall dort sinnvoll, wo man in einem C-Programm zur Lösung des Problems einen Funktionszeiger eingesetzt hätte (oder in Assembler eine Einsprung-Adresse in Maschinencode hinterlegt oder übergeben hätte).

Werden Methoden in C++ unnötigerweise "virtual" deklariert (mit anderen Worten: steht die Einsprungadresse immer fest und hätte insofern auch der Compiler oder Linker sie bestimmen können), so ist der Overhead natürlich unnötig - aber auch leicht vermeidbar, indem man solche Methoden eben nicht als "virtual" deklariert.

Dort, wo sinnvoll, also wo virtuelle Methoden tatsächlich ein Problem lösen helfen, sind sie in der Regel eleganter und programmiertechnisch einfacher zu handhaben als explizite Funktionszeiger.

Interfaces (Abstrakte Basisklassen)

Abstrakte Basisklassen sind im Grunde genommen Bündel von Funktionszeiger und ebenso wie virtuelle Methoden genau dort sinnvoll, wo sie ein Problem lösen helfen. Hierzu ein Beispiel: Ein Embedded-System hat eine Verbindung zu einem Host-Rechner zwecks Datenaustausch. Es besteht entweder ein LAN-Zugang oder an der seriellen Schnittstelle hängt ein Modem. Möglicherweise kommt es im laufenden Betrieb auch zu einer Umkonfiguration oder die Hostverbindung fällt komplett aus, dann sollen die Daten in einem lokalen, nicht-flüchtigen Speicher abgelegt werden.

Damit die Applikation nicht alle Eventualitäten an zahlreichen Stellen des Programms verteilt berücksichtigen muss, abstrahiert man den Datenaustausch z.B.

  • Verbindung initiieren
  • Daten übergeben
  • Übernahme bestätigen
  • Verbindung abbauen

in einem Interface. Jede der genannten Operationen entspricht dabei einem Zeiger auf ein entsprechendes Unterprogramm (also dessen Einsprungadresse). Tatsächlich implementiert werden diese Unterprogramme mehrfach (einmal für LAN, einmal für Modem, einmal für lokalen Speicher) und der eigentlichen Applikation wird - mehr oder weniger transparent - einfach das passende Funktionszeigerbündel übergeben, je nachdem, welche Art von Host-Verbindung derzeit möglich ist.

Auch hier ist es wieder so, dass ein Interface - realisiert durch eine abstrakte Basisklasse - im Vergleich zu expliziten Funktionszeigern eleganter und programmiertechnisch einfacher ausfällt (sofern man einmal das Prinzip verstanden hat). Ebenso gilt, dass abstrakte Basisklassen zu unnötigem Overhead führen, falls man sie "nur mal so" einsetzt, also ohne dass sie, wie oben dargestellt, ein konkretes Problem lösen.

Exceptions (Ausnahmebehandlung)

Mit Exceptions lässt sich ein "alternativer Kontrollfluss" in einem Programm definieren, vorzugsweise zur Handhabung von Fehlersituationen oder anderer "außergewöhnlicher Ereignisse". Mit der Einführung von Exceptions musste in C++ aber auch die Leitlinie "You only pay for what you use" verletzt werden. Das heißt es entsteht stets etwas Overhead, wenn der C++-Compiler Exceptions unterstützt, auch für Programme, die Execptions überhaupt nicht benutzen. Aus diesem Grund lassen sich Execptions über Kommandozeilen-Argumente des Compilers oder in den Projekt-Optionen einer Tool-Chain häufig deaktivieren.

Laufzeit-Typinformation

Laufzeit-Typinformation (auch Runtime Type Information oder RTTI genannt), verursacht unter Umständen ebenfalls einen geringen Overhead in C++, auch wenn ein Programm RTTI nicht benutzt. Insofern gilt wie für Exceptions, dass man ggf. nach einer Möglichkeit suchen sollte, RTTI ganz abzuschalten, wenn man das Feature nicht braucht. Auf der anderen Seite ist der RTTI-Overhead im Vergleich zu Exceptions sehr gering und entsteht vor allem im Hinblick auf ein wenig zusätzlich benötigten Speicherplatz, nicht in Form unnötig ausgeführter Anweisungen. (Nach Abschalten der RTTI-Unterstützung darf man also kein "schnelleres" Programm erwarten.)

Templates (Schablonen)

Templates sind ein Mechanismus, der zwischen Implementierungs- und Kompilierungs-Zeitpunkt greift. Im Grunde genommen steht mit einer C++-Template "ein bisschen Programmcode" stellvertretend für "möglicherweise sehr viel Programmcode", der aber noch in einem bestimmten Aspekt - einem Datentyp oder eine Konstante - variieren kann. Der allgemeine Teil (Template) wird nur einmalig implementiert und später in mehr oder weniger vielen Varianten kompiliert. (Das am ehesten vergleichbare äquivalent zu C++-Templates sind in C die Präprozessor-Makros.)

Unter diesem Aspekt betrachtet sind Templates keine Verschwendung (wie manchmal behauptet) sondern sehr sparsam und ideal für Mikrocontroller, da sie im Vergleich zu einer Bibliotheksfunktionen, die quasi "auf Vorrat" viele Varianten berücksichtigen, von denen konkret aber nicht alle genutzt werden, einem Programm nur das hinzufügt, was wirklich benötigt wird.

Auf der anderen Seite sind Templates ein neueres Feature von C++ zu dem bis vor wenigen Jahren auf Seite der Compiler-Lieferanten kaum Erfahrung hinsichtlich der optimalen Umsetzung bestand. Auch in der Fachliteratur werden Templates meist mit viel geringerer Tiefe und weniger Praxisbezug behandelt als diejenigen Features, die schon sehr lange von C++ unterstützt werden (Vererbung usw.). Eine generelle Empfehlung, Templates bei der Verwendung von C++ im Bereich der Mikrocontroller-Programmierung nicht einzusetzen, ist daraus aber keinesfalls abzuleiten - ganz im Gegenteil: Zur Lösung vieler Probleme sind Templates besser geeignet als etwa Präprozessor-Makros oder gar Copy-und-Paste-Programmierung.

C vs C++ – Mikrocontroller.net (2024)

References

Top Articles
Transportmöglichkeiten, um Dublin zu erkunden | Ireland.com
Sydney Convicts, History & The Rocks 2.5-Hour Walking Tour
Is Sam's Club Plus worth it? What to know about the premium warehouse membership before you sign up
Chris wragge hi-res stock photography and images - Alamy
How to change your Android phone's default Google account
Miles City Montana Craigslist
Routing Number 041203824
New Day Usa Blonde Spokeswoman 2022
Tv Schedule Today No Cable
UEQ - User Experience Questionnaire: UX Testing schnell und einfach
WWE-Heldin Nikki A.S.H. verzückt Fans und Kollegen
Top tips for getting around Buenos Aires
Marvon McCray Update: Did He Pass Away Or Is He Still Alive?
Sprinkler Lv2
Full Standard Operating Guideline Manual | Springfield, MO
Gopher Hockey Forum
Tinker Repo
Christina Steele And Nathaniel Hadley Novel
Milanka Kudel Telegram
Busted Mcpherson Newspaper
Jeff Nippard Push Pull Program Pdf
FAQ's - KidCheck
Marokko houdt honderden mensen tegen die illegaal grens met Spaanse stad Ceuta wilden oversteken
897 W Valley Blvd
5 Star Rated Nail Salons Near Me
Publix Coral Way And 147
Wcostream Attack On Titan
Graphic Look Inside Jeffrey Dresser
67-72 Chevy Truck Parts Craigslist
Frostbite Blaster
Log in or sign up to view
That1Iggirl Mega
Marcus Roberts 1040 Answers
Winco Money Order Hours
Blackstone Launchpad Ucf
Anhedönia Last Name Origin
St Anthony Hospital Crown Point Visiting Hours
Vons Credit Union Routing Number
Tripadvisor Vancouver Restaurants
Walgreens On Secor And Alexis
Squalicum Family Medicine
Iupui Course Search
Rise Meadville Reviews
A rough Sunday for some of the NFL's best teams in 2023 led to the three biggest upsets: Analysis
Kate Spade Outlet Altoona
Worland Wy Directions
Missed Connections Dayton Ohio
Definition of WMT
Fredatmcd.read.inkling.com
Vcuapi
Craigslist Monterrey Ca
O'reilly's Eastman Georgia
Latest Posts
Article information

Author: Fredrick Kertzmann

Last Updated:

Views: 5477

Rating: 4.6 / 5 (46 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Fredrick Kertzmann

Birthday: 2000-04-29

Address: Apt. 203 613 Huels Gateway, Ralphtown, LA 40204

Phone: +2135150832870

Job: Regional Design Producer

Hobby: Nordic skating, Lacemaking, Mountain biking, Rowing, Gardening, Water sports, role-playing games

Introduction: My name is Fredrick Kertzmann, I am a gleaming, encouraging, inexpensive, thankful, tender, quaint, precious person who loves writing and wants to share my knowledge and understanding with you.