Eine häufig gestellte Frage, hier und anderswo. Ist C++ für eingebettete Systeme geeignet?
Mikrocontroller? Echtzeitbetriebssysteme? Toaster? Embedded-PCs?
Ist OOP auf Mikrocontrollern nützlich?
Entfernt C++ den Programmierer zu weit von der Hardware, um effizient zu sein?
Sollte Arduinos C++ (ohne dynamische Speicherverwaltung, Vorlagen, Ausnahmen) als "echtes C++" betrachtet werden?
(Hoffentlich dient dieses Wiki als Ort, um diesen potenziellen heiligen Krieg einzudämmen)
Ja, C++ ist in eingebetteten Systemen immer noch nützlich. Wie alle anderen gesagt haben, hängt es immer noch vom System selbst ab, wie ein 8-Bit-uC in meinem Buch wahrscheinlich ein No-No wäre, obwohl es einen Compiler gibt und einige Leute es tun (schaudern). Die Verwendung von C++ hat immer noch einen Vorteil, selbst wenn Sie es auf etwas wie "C+" herunterskalieren, selbst in einer 8-Bit-Mikrowelt. Was meine ich mit "C+"? Ich meine, verwenden Sie nicht new/delete, vermeiden Sie Ausnahmen, vermeiden Sie virtuelle Klassen mit Vererbung, vermeiden Sie möglicherweise Vererbung insgesamt, seien Sie sehr vorsichtig mit Vorlagen, verwenden Sie Inline-Funktionen anstelle von Makros und verwenden Sie const
Variablen anstelle von #defines
.
Ich arbeite jetzt seit weit über einem Jahrzehnt sowohl in C als auch in C++ in eingebetteten Systemen, und ein Teil meiner jugendlichen Begeisterung für C++ ist aufgrund einiger realer Probleme, die die Naivität erschüttern, definitiv nachgelassen. Ich habe das Schlimmste von C++ in einem eingebetteten System gesehen, das ich als „CS-Programmierer, die in einer EE-Welt wild geworden sind“ bezeichnen möchte. Daran arbeite ich tatsächlich mit meinem Kunden, um unter anderem diese eine Codebasis zu verbessern.
Die Gefahr von C++ besteht darin, dass es ein sehr, sehr mächtiges Werkzeug ist, ähnlich wie ein zweischneidiges Schwert, das Ihnen sowohl den Arm als auch das Bein abschneiden kann, wenn Sie nicht richtig in seiner Sprache und der allgemeinen Programmierung selbst ausgebildet und diszipliniert sind. C ist eher wie ein einschneidiges Schwert, aber immer noch genauso scharf. Mit C++ ist es zu einfach, sehr hohe Abstraktionsebenen zu erreichen und verschleierte Schnittstellen zu erstellen, die auf lange Sicht bedeutungslos werden, und das liegt teilweise an der Flexibilität von C++, dasselbe Problem mit vielen verschiedenen Sprachfunktionen (Vorlagen, OOP, prozedurale, RTTI, OOP+Templates, Überladen, Inlining).
Ich habe zwei 4-stündige Seminare über eingebettete Software in C++ von dem C++-Guru Scott Meyers absolviert. Er wies auf einige Dinge über Vorlagen hin, die ich zuvor nie in Betracht gezogen hatte, und wie viel mehr sie beim Erstellen von sicherheitskritischem Code helfen können. Die Quintessenz ist, dass Sie keinen toten Code in Software haben können, die strenge sicherheitskritische Codeanforderungen erfüllen muss. Vorlagen können Ihnen dabei helfen, da der Compiler nur den Code erstellt, den er beim Instanziieren von Vorlagen benötigt. Man muss sich jedoch gründlicher in ihrer Verwendung ausbilden, um für dieses Feature richtig zu entwerfen, was in C schwieriger zu erreichen ist, da Linker nicht immer toten Code optimieren.
Scott Meyers ist ein sehr großer Befürworter von Templates und der vernünftigen Verwendung von Inlining, und ich muss sagen, dass ich immer noch skeptisch bin, was Templates betrifft. Ich neige dazu, davor zurückzuschrecken, obwohl er sagt, dass sie nur dort angewendet werden sollten, wo sie das beste Werkzeug werden. Er weist auch darauf hin, dass C++ Ihnen die Werkzeuge gibt, um wirklich gute Schnittstellen zu erstellen, die einfach richtig zu verwenden sind und es schwierig machen, sie falsch zu verwenden. Auch das ist der schwierige Teil. Man muss C++ beherrschen, bevor man weiß, wie man diese Funktionen am effizientesten anwendet, um die beste Designlösung zu sein.
Dasselbe gilt für OOP. In der eingebetteten Welt müssen Sie sich damit vertraut machen, welche Art von Code der Compiler ausspuckt, um zu wissen, ob Sie die Laufzeitkosten des Laufzeitpolymorphismus bewältigen können. Sie müssen bereit sein, auch Messungen vorzunehmen, um zu beweisen, dass Ihr Design Ihre Terminanforderungen erfüllt. Wird diese neue InterruptManager-Klasse meine Interrupt-Latenz zu lang machen? Es gibt andere Formen von Polymorphismus, die möglicherweise besser zu Ihrem Problem passen, wie z .
Ich sage das nur, um zu sagen, dass C++ seinen Platz in der Embedded-Welt hat. Du kannst es hassen, so viel du willst, aber es geht nicht weg. Es kann auf sehr effiziente Weise geschrieben werden, aber es ist schwieriger zu lernen, wie man es richtig macht, als mit C. Es kann manchmal besser als C funktionieren, um ein Problem zu lösen und manchmal eine bessere Schnittstelle auszudrücken, aber auch hier müssen Sie es tun bilden Sie sich und haben Sie keine Angst zu lernen, wie.
On the note of Computer Science majors going crazy in EE land ...
--> wir hatten einmal einige CS Professional Consultants bei uns, die viele Jahre Erfahrung hatten und die darauf bestanden, dass Programmieren ausnahmslos einfach nur ekelhaft ist. Sie aktivierten Ausnahmen mit -fexceptions
auf den eingebetteten Controllern (was vom Hersteller dieser Controller aktiv entmutigt wurde), während sie sich beschwerten, dass EE-Leute Software einfach nicht verstanden und einfach so oder so Ausnahmen auslösten. (-‸ლ) Nach ein paar Jahre in der Entwicklungshölle starb das Projekt.C++ ist absolut geeignet für eingebettete Systeme. Ich benutze jetzt das Vorhandensein/Fehlen guter Entwicklungswerkzeuge (oder deren Fehlen) als mein Hauptkriterium dafür, ob ich einen bestimmten Mikroprozessor verwenden soll oder nicht.
Bereiche von C++, die sich gut für eingebettete Systeme eignen, da sie geringe Ressourcenkosten haben:
OK-Bereiche:
Nicht zu verwendende Bereiche, hauptsächlich wegen des Laufzeit-Overheads, der auf kleinen Systemen nicht akzeptabel ist:
foo
aufruft und einige Objekte erstellt und aufruft , was eine Ausnahme auslöst, das System irgendwie die Destruktoren für die erstellten Objekte aufrufen muss, bevor es die Kontrolle an zurückgibt . Wenn Ausnahmen nicht vollständig deaktiviert sind, kann es nicht wissen, ob möglicherweise welche ausgelöst werden, und muss daher zusätzlichen Code enthalten, um diese Möglichkeit zu ermöglichen. Ich würde gerne eine Variante von C++ mit "geprüften Ausnahmen" sehen, um damit umzugehen; Wenn Routinen, die Ausnahmen zulassen könnten, entkommen ...
bar
try
catch
bar
boz
bar
foo
bar
boz
add r15,r14,#2
statt mit mov r15,r14
; über eine Ausnahme beenden, ldrhs r0,[r14] / add r15,r14,r0
. Null Zykluskosten für den normalen Ausgang und keine Stack-Frame-Einschränkungen.throw
Code die finden kann catch
, entweder indem der C- oder Assembler-Code einem Strict folgen muss Stack-Frame-Protokoll, oder verwenden Sie einen statischen Speicherort, um die erforderlichen Informationen oder einen Zeiger darauf zu speichern.foo
die Assembler-Sprachroutine aufruft bar
, die vor dem Aufruf der C++-Routine unbekannte beliebige Daten auf den Stapel legt boz
und boz
eine Ausnahme auslöst, muss das System irgendwie den Stapelrahmen von finden foo
. Dies kann nicht geschehen, ohne entweder die Assembler-Routine bar
zu ändern, um ihren anfänglichen Stack-Pointer-Wert für den aufgerufenen Code verfügbar zu machen, oder den Multitasker zu ändern, um einen statischen Ausnahme-Frame-Zeiger zu speichern/wiederherstellen.Ja, C++ ist durchaus für eingebettete Systeme geeignet. Lassen Sie uns zunächst ein paar Missverständnisse über den Unterschied zwischen C und C++ aufklären:
In einem eingebetteten Mikro müssen Sie Hochsprachen immer sorgfältig verwenden, wenn Sie sich Sorgen um Zeit- oder Platzbeschränkungen machen. Zum Beispiel handhaben viele MCUs Zeiger nicht gut und sind daher sehr ineffizient, wenn sie den Stack verwenden. Das bedeutet, dass Sie vorsichtig sein müssen, wenn Sie Variablen an Funktionen übergeben, Arrays und Zeiger verwenden und Rekursionen verwenden. Eine einfache Zeile von C wie:
a[i] = b[j] * c[k];
kann je nach Art dieser Variablen etwa 4 Seiten mit Anweisungen generieren.
Wann immer Sie eine Hochsprache verwenden und sich Sorgen um Zeit- und Platzbeschränkungen machen, müssen Sie wissen, wie jede Funktion dieser Sprache in Maschinenanweisungen auf Ihrer MCU übersetzt wird (zumindest jede Funktion, die Sie verwenden). Das gilt für C, C++, Ada, was auch immer. Wahrscheinlich enthalten alle Sprachen Funktionen, die auf kleinen MCUs nicht effizient übersetzt werden können. Überprüfen Sie immer die Disassemblierungslisten, um sicherzustellen, dass der Compiler nicht Unmengen von Anweisungen für etwas Triviales generiert.
Ist C für eingebettete MCUs geeignet? Ja, solange Sie den generierten Code im Auge behalten.
Ist C++ für eingebettete MCUs geeignet? Ja, solange Sie den generierten Code im Auge behalten.
Deshalb denke ich, dass C++ sogar auf 8-Bit-MCUs besser ist als C: C++ bietet verbesserte Unterstützung für:
Keines dieser Merkmale ist schwerer als typische Merkmale von C.
Wenn Sie auf 16- oder 32-Bit-MCUs aufsteigen, wird es sinnvoll, schwerere Funktionen von C (Stack, Heap, Pointer, Arrays, Printf usw.) zu verwenden. Auf die gleiche Weise wird es auf einer leistungsfähigeren MCU angemessen schwerere Funktionen von C++ zu verwenden (Stack, Heap, Referenzen, STL, Neu/Löschen).
Bei dem Gedanken an C++ auf einem PIC16 braucht man also nicht zu schaudern. Wenn Sie Ihre Sprache und Ihre MCU richtig kennen, wissen Sie, wie Sie beide effektiv zusammen verwenden können.
a[i] = b[j] * c[k];
kann abhängig von der Art dieser Variablen etwa 4 Seiten mit Anweisungen generieren." Wenn Ihr MCU / Compiler dies tut, liegt dies daran, dass Sie eine Garagen-Hobby-CPU aus den 80er Jahren verwenden.Ich finde diese Debatten immer unterhaltsam zu lesen. Nicht so sehr für die intellektuelle Diskussion über die Vor- und Nachteile der verschiedenen verfügbaren Sprachen, sondern weil Sie normalerweise die Haltung einer Person zum Thema anhand ihres Jobs / ihrer Erfahrung / ihres Interessengebiets festmachen können. Es ist genau dort oben mit den Argumenten der "vorzeitigen Optimierung", wo die CS-Majors und Wartungsprogrammierer Knuth links und rechts zitieren und diejenigen, die in der realen Welt arbeiten, wo Leistung wichtig ist, denken, dass sie alle verrückt sind (ich bin ein Mitglied der letzteren Gruppe um fair zu sein).
Letztendlich kann man hier hervorragende Software in C oder C++ entwickeln oder Sprache einfügen . Es kommt auf die Fähigkeiten des Entwicklers an, nicht auf die Sprache. Ein Experte in einer Sprache zu sein, ist normalerweise nur erforderlich, wenn Sie anfangs die falsche Sprache gewählt haben und sie nun zur Lösung Ihres Problems verzerren müssen. In den meisten Fällen sind dies die einzigen Situationen, in denen Sie in obskure Funktionen oder Compiler eintauchen müssen Tricks, um das Ziel zu erreichen.
Ich höre oft, wie Leute diese Argumente mit "Ich bin ein Experte in Sprache X und bla bla" beginnen. Ich diskreditiere diese Leute ehrlich gesagt sofort, weil sie meiner Meinung nach das Problem bereits aus der falschen Perspektive angegangen sind und alles danach verdorben ist durch ihren Wunsch, ihr Werkzeug zu verwenden, um das Problem zu lösen und zu zeigen, wie "cool" es ist.
Ich beobachte so oft, wie Entwickler zuerst ein Tool-Set auswählen und dann versuchen, es an ihr Problem anzupassen, was völlig falsch ist und zu beschissenen Lösungen führt.
Wie ich in einem Kommentar zu einer anderen Antwort erwähnt habe, führen diese Sprachkriege oft zu der Argumentation, dass Sprache X dem Programmierer erlaubt, dummere Dinge zu tun. Obwohl es unterhaltsam zu lesen ist, bedeuten all diese Aussagen in Wirklichkeit, dass Sie ein Problem damit haben, gute Entwickler einzustellen, und dieses Problem direkt angehen müssen, anstatt zu versuchen, die Situation zu lindern, indem Sie weiterhin schlechte Entwickler einstellen und Tools so auswählen, dass sie so wenig tun können Schaden wie möglich.
Meiner Meinung nach erforschen gute Entwickler, sei es Software- oder Hardwareentwicklung, das Problem, entwerfen eine Lösung und finden die Werkzeuge, mit denen sie die Lösung auf die „beste Art und Weise“ ausdrücken können. Es sollte keine Rolle spielen, ob das erforderliche Tool etwas ist, das Sie noch nie zuvor verwendet haben, nachdem Sie 3-4 Sprachen/Entwicklungstools für Projekte verwendet haben, sollte die Aufnahme eines neuen eine minimale Auswirkung auf Ihre Entwicklungszeit haben.
„Best Way“ ist natürlich ein subjektiver Begriff und muss auch in der Recherchephase definiert werden. Man muss eine Vielzahl von Aspekten berücksichtigen: Leistung, einfache Ausdrucksweise, Codedichte usw., je nach vorliegendem Problem. Ich habe die Wartbarkeit aus einem bestimmten Grund nicht in diese Liste aufgenommen, es ist mir egal, welche Sprache Sie wählen, wenn Sie das richtige Tool ausgewählt und sich die Zeit genommen haben, das Problem zu verstehen, sollte dies "kostenlos" kommen. Schwierig zu wartender Code ist oft das Ergebnis der Wahl des falschen Tools oder einer schlechten Systemstruktur, was zu einem hässlichen Durcheinander führt, damit es funktioniert.
Zu behaupten, eine Sprache sei „besser“ als jede andere, ist albern, ohne ein bestimmtes Problem von Interesse zu definieren. Ein objektorientierter Ansatz ist nicht immer besser als ein funktionaler Ansatz. Es gibt einige Probleme, die sich sehr gut für ein objektorientiertes Entwurfsparadigma eignen. Es gibt viele, die das nicht tun. Die gleiche Aussage kann über viele Sprachmerkmale gemacht werden, auf denen die Leute gerne herumreiten.
Wenn Sie mehr als 20 % Ihrer Zeit für ein Problem damit verbringen, Code einzutippen, produzieren Sie wahrscheinlich ein sehr schlechtes System oder haben sehr schlechte Entwickler (oder Sie lernen noch). Sie sollten den größten Teil Ihrer Zeit damit verbringen, das Problem grafisch darzustellen und zu bestimmen, wie verschiedene Teile der Anwendung interagieren. Wenn Sie eine Gruppe talentierter Entwickler in einen Raum mit einer Markierungstafel und einem zu lösenden Problem stecken und ihnen sagen, dass sie keinen Code schreiben oder keine Tools auswählen dürfen, bis sie sich mit dem gesamten System wohl fühlen, wird dies mehr zur Verbesserung der Qualität beitragen Leistung und Entwicklungsgeschwindigkeit, als die Wahl eines heißen neuen Tools, das garantiert die Entwicklungszeit verkürzt. (Schauen Sie sich die Scrum-Entwicklung als Referenz für das genaue Gegenteil meiner Argumentation an)
Die unglückliche Realität ist oft, dass viele Unternehmen den Wert eines Entwicklers nur an der Anzahl der geschriebenen Zeilen oder am „greifbaren Ergebnis“ messen können. Sie betrachten die 3 Wochen in einem Raum mit einer Markierungstafel als Produktivitätsverlust. Entwickler werden oft gezwungen, durch die „Gedanken“-Phase der Entwicklung zu eilen oder werden durch ein politisches Problem innerhalb des Unternehmens gezwungen, ein Toolset zu verwenden, „Der Bruder meines Chefs arbeitet für IBM, also können wir nur ihre Tools verwenden“, diese Art von Müll . Oder noch schlimmer, Sie erhalten ständig wechselnde Anforderungen vom Unternehmen, weil sie nicht in der Lage sind, angemessene Marktforschung zu betreiben oder die Auswirkungen von Änderungen auf den Entwicklungszyklus nicht verstehen.
Tut mir leid, dass ich mit diesem Geschwätz etwas vom Thema abgekommen bin, ich habe ziemlich starke Meinungen zu diesem Thema.
Meiner Erfahrung nach ist C++ für kleine eingebettete Systeme normalerweise schlecht geeignet. Damit meine ich Mikrocontroller und Geräte ohne Betriebssystem.
Viele C++-OOP-Techniken beruhen auf dynamischer Speicherzuordnung. Das fehlt oft in kleinen Anlagen.
STL und Boost demonstrieren wirklich die Leistungsfähigkeit von C++, beide haben einen enormen Platzbedarf.
C++ ermutigt den Programmierer, die Maschine zu abstrahieren, wo sie in eingeschränkten Systemen umarmt werden muss.
Letztes Jahr habe ich ein kommerzielles Remote-Desktop-Produkt auf Mobiltelefone portiert. Es wurde in C++ geschrieben und lief unter Windows, Linux und OSX. Aber es stützte sich stark auf STL, dynamischen Speicher und C++-Ausnahmen. Um es auf WinCE, Symbian und OS-losen Umgebungen zum Laufen zu bringen, war ein C-Rewrite die vernünftigste Option.
Jede Sprache kann für ein eingebettetes System geeignet sein. Eingebettet bedeutet nur: Teil eines größeren Apparats, im Gegensatz zu einem frei nutzbaren Computer.
Die Frage ist relevanter, wenn sie nach einem (harten) Echtzeit- oder einem System mit begrenzten Ressourcen gestellt wird.
Für ein Echtzeitsystem ist C++ eine der höchsten Programmiersprachen, die noch für die Programmierung unter strengen Zeitvorgaben geeignet ist. Mit Ausnahme der Heap-Nutzung (freier Operator) gibt es keine Konstrukte, die eine unbestimmte Ausführungszeit haben, sodass Sie testen können, ob Ihr Programm seine Timing-Anforderungen erfüllt, und mit etwas mehr Erfahrung können Sie es vielleicht sogar vorhersagen. Die Heap-Nutzung sollte natürlich vermieden werden, obwohl der neue Operator immer noch für die einmalige Zuweisung verwendet werden kann. Die Konstrukte, die C++ über C bietet, können in einem eingebetteten System sinnvoll eingesetzt werden: OO, Exceptions, Templates.
Für sehr ressourcenbeschränkte Systeme (8-Bit-Chips, weniger als ein paar Kb RAM, kein zugänglicher Stack) könnte vollständiges C++ ungeeignet sein, obwohl es immer noch als 'besseres C' verwendet werden könnte.
Ich finde es schade, dass Ada nur in einigen Nischen eingesetzt zu werden scheint. In vielerlei Hinsicht ist es ein Pascal++, aber ohne die Bürde, mit einer Sprache aufwärtskompatibel zu sein, die schon von Anfang an ein großes Durcheinander war. (Bearbeiten: Das ernsthafte Durcheinander ist natürlich C. Pascal ist eine schöne, aber etwas unpraktische Sprache.)
=============================================== ==============
BEARBEITEN: Ich habe eine Antwort auf eine neue Frage eingegeben ("In welchen Fällen ist C ++ erforderlich, wenn wir Mikrocontroller programmieren"? ), die sich auf diese bezieht, also füge ich hinzu, was ich geschrieben habe:
Es gibt nie einen allumfassenden Grund für die Verwendung einer Programmiersprache, aber es kann Argumente geben, die in einer bestimmten Situation mehr oder weniger Gewicht haben. Diskussionen darüber finden sich an vielen Stellen, wobei Positionen vertreten werden, die von „niemals C++ für einen Mikrocontroller verwenden“ bis „immer C++ verwenden“ reichen. Ich bin eher mit der letzten Position. Ich kann einige Argumente anführen, aber Sie müssen selbst entscheiden, wie viel Gewicht sie in einer bestimmten Situation haben (und in welche Richtung).
Mein Blog enthält einige Schriften zur Verwendung von C++ auf kleinen Systemen (= Mikrocontrollern).
Ich hoffe, dieser Diskussion über C++ auf Bare-Metal- und ressourcenbeschränkten Systemen mehr Licht als Wärme hinzufügen zu können.
Probleme in C++:
Ausnahmen sind insbesondere ein RAM-Problem, da der erforderliche "Notfallpuffer" (wo beispielsweise die Ausnahme wegen fehlendem Speicher gilt) größer sein kann als der verfügbare RAM und für Mikrocontroller sicherlich eine Verschwendung ist. Weitere Informationen finden Sie unter n4049 und n4234 . Sie sollten ausgeschaltet werden (was derzeit ein nicht spezifiziertes Verhalten ist, also seien Sie sicher und werfen Sie es niemals). SG14 arbeitet derzeit an besseren Möglichkeiten, dies zu tun.
RTTI ist wahrscheinlich nie den Mehraufwand wert, es sollte abgeschaltet werden
Große Debug-Builds, obwohl dies in der klassischen Desktop-Entwicklung kein Problem darstellt, wenn das Debug nicht auf den Chip passt, kann es ein Problem sein. Das Problem ergibt sich aus Codevorlagen oder zusätzlichen Funktionsaufrufen, die der Übersichtlichkeit halber hinzugefügt wurden. Diese zusätzlichen Funktionsaufrufe werden vom Optimierer wieder entfernt und die zusätzliche Klarheit oder Flexibilität kann ein großer Vorteil sein, jedoch kann dies in Debug-Builds ein Problem sein.
Heap-Zuweisung. Obwohl die STL die Verwendung von benutzerdefinierten Zuweisungen zulässt, kann dies für die meisten Programmierer komplex sein. Die Heap-Zuweisung ist nicht deterministisch (dh keine harte Echtzeit) und die Fragmentierung kann zu unerwarteten Speichermangelsituationen führen, die auftreten, obwohl beim Testen gearbeitet wurde. Die Buchhaltung, die der Haufen benötigt, um den freien Platz und die unterschiedliche Größe zu verfolgen, kann bei kleinen Objekten ein Problem sein. Es ist normalerweise besser, die Pool-Zuweisung zu verwenden (sowohl in C als auch in C++), aber dies kann für C++-Programmierer ungewöhnlich sein, die daran gewöhnt sind, nur den Heap zu verwenden.
Laufzeitpolymorphismus und andere indirekte Aufrufe sind normalerweise ein großer Leistungseinbruch, das Problem liegt normalerweise eher darin, dass der Optimierer nicht mehr durch sie hindurchsehen kann, als das eigentliche Abrufen und Springen zu der Adresse. Indirekte Aufrufe sind aus diesem Grund in C und C++ zu vermeiden, wo sie wie in C++ stärker in der Kultur verwurzelt sind (und in anderen Domänen sehr nützlich sind).
Die implizite Anbindung an clib kann problematisch sein. Es mag widersprüchlich sein, dass clib-Probleme in die C++-Kategorie fallen, aber das Problem ergibt sich aus der impliziten gemeinsamen Nutzung von Ressourcen in gleichzeitigen Umgebungen (die gemeinsame Nutzung ist in C expliziter). Die Verwendung der gemeinsamen newLib-Implementierung zieht oft eine Menge Bloat mit sich, was normalerweise in uCs nicht benötigt wird, andererseits ist newLibNanno nicht reentrant, sodass der Zugriff darauf serialisiert werden muss (hier zu stark vereinfacht). Dies ist auch ein Problem für C, aber der Zugriff ist expliziter. Als Faustregel sollte man im ISR-Kontext im Wesentlichen nichts aus dem Namensraum std verwenden, es sei denn, Sie sind sicher, dass es nicht irgendwie auf den Status in clib zugreift (zum Beispiel errorno oder der Heap). Es ist auch wichtig, wenn Sie Threads verwenden (ich bevorzuge RTC), um new und delete zu überschreiben, um den Zugriff auf malloc und free zu synchronisieren.
Zusammenfassend lässt sich sagen, dass C++ einige Probleme hat, die aber im Wesentlichen alle behebbar oder vermeidbar sind.
Jetzt für C, hier ist das Problem höherer Ordnung. Ich habe in C nicht die syntaktische Fähigkeit, Dinge so zu abstrahieren, dass ich Optimierungen durchführen oder Invarianten zur Kompilierzeit überprüfen kann. Daher kann ich Dinge nicht richtig so kapseln, dass der Benutzer nicht wissen muss, wie sie funktionieren, um sie zu verwenden, und der Großteil meiner Fehlererkennung erfolgt zur Laufzeit (was nicht nur zu spät ist, sondern auch Kosten verursacht). Im Wesentlichen ist die einzige Möglichkeit, in C generisch zu sein, über Daten. Ich übergebe einen Formatstring an printf oder scanf, der zum Beispiel zur Laufzeit ausgewertet wird. Es ist dann ziemlich schwierig für den Compiler zu beweisen, dass ich einige der Optionen nicht verwende, die theoretisch möglich sind, wenn die richtigen Daten übergeben werden, was eine potenzielle Generierung von totem Code und den Verlust von Optimierungspotenzial bedeutet.
Ich weiß, dass ich hier vielleicht einen Shitstorm entfessele, aber meine Erfahrung mit 32-Bit-Mikrocontrollern ist, dass in einem Äpfel-zu-Äpfel-Vergleich von C und C++, die beide von Experten geschrieben wurden (wie in C++ möglicherweise stark vorlagenbasiert), C++ die viel effizientere Sprache ist alles muss überhaupt generisch sein (wie in jeder Bibliothek) und sie sind in nicht generischen Fällen im Wesentlichen äquivalent. Es ist auch für einen Anfänger einfacher, das Fachwissen eines erfahrenen Bibliotheksimplementierers in C++ zu nutzen.
Gleichzeitig gibt es eigentlich nur wenige Funktionen, an die ich keine falschen Daten übergeben kann, sobald die Eingabe kein int ist, sondern eine, something
für die ich zufällig ein int als Darstellungsmethode verwende, besteht die Möglichkeit, es zu bekommen falsch (übergeben Sie einen ungültigen Wert oder ein 'otherThing' anstelle von 'something'). In C ist meine einzige Methode, um zu überprüfen, ob der Benutzer etwas falsch gemacht hat, zur Laufzeit. In C++ habe ich die Möglichkeit, einige Prüfungen durchzuführen, nicht alle Prüfungen, aber einige Prüfungen zur Kompilierzeit, die kostenlos sind.
Am Ende des Tages ist ein C-Team oft so mächtig wie sein schwächster Programmierer und der daraus resultierende Code hat entweder einen Multiplayer von 1 oder eine Leistungsstrafe. Was ich damit meine, ist, dass es entweder eine hohe Leistung für einen und nur einen einzigartigen Job in einer einzigartigen Umgebung mit einzigartigen Designentscheidungen ist oder dass es generisch genug ist, um in mehreren Umgebungen verwendet zu werden (anderer Mikrocontroller, andere Speicherverwaltungsstrategie, andere Latenz vs. Durchsatzkompromisse usw. usw.), hat aber inhärente Leistungskosten.
In C++ können Dinge von Experten gekapselt und in vielen Umgebungen verwendet werden, in denen sich die Codegenerierung zur Kompilierzeit an die jeweilige Aufgabe anpasst und die statische Überprüfung die Benutzer davon abhält, dummes Zeug zum Nulltarif zu machen. Hier müssen wir weitaus weniger Kompromisse zwischen generisch und schnell machen und sind daher letztendlich aus Kosten-Nutzen-Sicht die leistungsfähigere, sicherere und produktivere Sprache.
Es ist eine berechtigte Kritik, dass es immer noch einen großen Mangel an guten C++-Bibliotheken für Embedded gibt, was zu pragmatischen Entscheidungen führen kann, hauptsächlich C auf einem C++-Compiler zu verwenden. Entscheidungen, in einem Projekt nur C zu verwenden, sind im Wesentlichen entweder ideologisch motiviert, aus der Notwendigkeit von Legacy-Unterstützung oder aus dem Eingeständnis, dass das Team nicht diszipliniert genug ist, um von einer sehr ausgewählten Reihe von dummen Dingen Abstand zu nehmen, die man in C++, aber nicht in C machen kann und gleichzeitig diszipliniert genug, um keine der weitaus größeren Dummheiten zu machen, vor denen man sich in C nicht schützen kann, aber in C++ könnte.
Mein Hintergrund: gerade aus der Schulausbildung bei alten Bell Labs-Programmierern; Arbeitet seit 3 Jahren, 2 an Bachelor-Forschungsprojekt; Datenerfassung / Prozesssteuerung in VB.NET. Verbrachte 1,5 Jahre mit der Arbeit an einer Unternehmensdatenbankanwendung in VB6. Arbeitet derzeit an einem Projekt für einen eingebetteten PC mit 2 GB Speicher, 512 MB RAM, 500 MHz x86-CPU; Mehrere Apps, die gleichzeitig ausgeführt werden und in C++ geschrieben sind, mit einem dazwischen liegenden IPC-Mechanismus. Ja, ich bin jung.
Meine Meinung: Ich denke, dass C++ angesichts der Umgebung, die ich oben geschrieben habe, effektiv funktionieren kann . Zugegeben, harte Echtzeitleistung ist keine Voraussetzung für die App, auf der ich mich befinde, und in einigen eingebetteten Anwendungen kann das ein Problem sein. Aber hier sind die Dinge, die ich gelernt habe:
C++ unterscheidet sich grundlegend von C (dh es gibt kein C/C++). Während alles, was gültiges C ist, gültiges C++ ist, ist C++ eine ganz andere Sprache und man muss lernen, wie man in C++ programmiert, nicht in C, um es in jeder Situation effektiv einzusetzen. In C++ müssen Sie objektorientiert programmieren, nicht prozedural und keine Mischung aus beidem (große Klassen mit vielen Funktionen). Im Allgemeinen sollten Sie sich darauf konzentrieren, kleine Klassen mit wenigen Funktionen zu erstellen, und alle kleinen Klassen zu einer größeren Lösung zusammensetzen. Einer meiner Kollegen erklärte mir, dass ich früher prozedural in Objekten programmiert habe, was ein großes Durcheinander ist und schwer zu warten ist. Als ich anfing, mehr objektorientierte Techniken anzuwenden, stellte ich fest, dass die Wartbarkeit/Lesbarkeit meines Codes zunahm.
C++ bietet zusätzliche Funktionen in Form von objektorientierter Entwicklung, die eine Möglichkeit bieten können, Code zu vereinfachen, um ihn leichter lesbar/verwaltbar zu machen . Ehrlich gesagt glaube ich nicht, dass einer Verbesserung der Leistung/Platzeffizienz bei OOP viel im Wege steht. Aber ich denke, OOP ist eine Technik, die helfen kann, ein komplexes Problem in viele kleine Teile aufzuteilen. Und das ist hilfreich für die Leute, die am Code arbeiten, ein Element dieses Prozesses, das nicht ignoriert werden sollte.
Viele Argumente gegen C++ haben in erster Linie mit dynamischer Speicherallokation zu tun. C hat das gleiche Problem auch. Sie können eine objektorientierte Anwendung schreiben, ohne dynamischen Speicher zu verwenden, obwohl einer der Vorteile der Verwendung von Objekten darin besteht, dass Sie diese Dinge auf einfache Weise dynamisch zuweisen können. Genau wie in C müssen Sie darauf achten, wie Sie die Daten verwalten, um Speicherlecks zu reduzieren, aber die RAII-Technik macht dies in C++ einfacher (lassen Sie den dynamischen Speicher automatisch zerstören, indem Sie ihn in Objekte kapseln). In einigen Anwendungen, wo jeder Speicherplatz zählt, kann dies zu wild und wollig sein, um es zu verwalten.
BEARBEITEN:
Ja, das Problem bei C++ ist der größere Platzbedarf des Codes.
In einigen Systemen zählen Sie Bytes, und in diesem Fall müssen Sie die Kosten für den Betrieb akzeptieren, die nahe an den Grenzen Ihres Systems liegen, nämlich erhöhte Entwicklungskosten von C.
Aber selbst in C müssen Sie für ein gut entworfenes System alles gekapselt halten. Gut entworfene Systeme sind schwierig, und C++ gibt Programmierern einen Platz für eine sehr strukturierte und kontrollierte Entwicklungsmethode. Das Erlernen von OOP ist mit Kosten verbunden, und wenn Sie darauf umsteigen möchten, akzeptieren Sie es sehr, und in vielen Fällen möchte das Management lieber mit C fortfahren und die Kosten nicht bezahlen, da es schwierig ist, die Ergebnisse eines solchen Umstiegs zu messen erhöht die Produktivität. Einen Artikel von Jack Ganssle, Guru für eingebettete Systeme, finden Sie hier .
Dynamisches Speichermanagement ist der Teufel. Nicht wirklich, der Teufel ist die automatische Weiterleitung, die dynamische Speicherverwaltung funktioniert auf einem PC hervorragend, aber Sie können davon ausgehen, dass Sie einen PC mindestens alle paar Wochen neu starten müssen. Sie werden feststellen, dass, wenn ein eingebettetes System 5 Jahre lang läuft, die dynamische Speicherverwaltung wirklich durcheinander geraten und tatsächlich versagen kann. Ganssle geht in seinem Artikel auf Dinge wie Stack und Heap ein.
Es gibt einige Dinge in C++, die anfälliger für Probleme sind und viele Ressourcen verbrauchen. Das Entfernen der dynamischen Speicherverwaltung und von Vorlagen sind große Schritte, um den Fußabdruck von C++ näher an dem Fußabdruck von C zu halten. Dies ist immer noch C++, Sie brauchen kein dynamisch Speicherverwaltung oder Vorlagen, um gutes C++ zu schreiben. Ich habe nicht bemerkt, dass sie Ausnahmen entfernt haben, ich betrachte Ausnahmen als einen wichtigen Teil meines Codes, den ich in der Version entferne, aber bis zu diesem Punkt verwende. In Feldtests kann ich Ausnahmen veranlassen, Nachrichten zu generieren, die mich darüber informieren, dass eine Ausnahme abgefangen wurde.
Ich fand diesen Anti-C++-Rant von Linus Torvalds interessant.
Eines der absolut schlimmsten Features von C++ ist, dass es viele Dinge so kontextabhängig macht - was einfach bedeutet, dass eine lokale Ansicht beim Betrachten des Codes einfach selten genug Kontext liefert, um zu wissen, was vor sich geht.
Er spricht nicht über die Welt der eingebetteten Systeme, sondern über die Linux-Kernel-Entwicklung. Für mich ergibt sich die Relevanz daraus: C++ erfordert das Verständnis eines größeren Kontexts, und ich kann lernen, eine Reihe von Objektvorlagen zu verwenden, ich traue mich nicht, mich an sie zu erinnern, wenn ich den Code in ein paar Monaten aktualisieren muss.
(Auf der anderen Seite arbeite ich derzeit an einem eingebetteten Gerät mit Python (nicht C++, aber mit dem gleichen OOP-Paradigma), das genau dieses Problem haben wird. Zu meiner Verteidigung ist es ein eingebettetes System, das leistungsfähig genug ist, um als PC bezeichnet zu werden vor 10 Jahren.)
Ich denke, andere Antworten haben die Vor- und Nachteile und Entscheidungsfaktoren ziemlich gut dargestellt, daher möchte ich nur zusammenfassen und ein paar Kommentare hinzufügen.
Für kleine Mikrocontroller (8-Bit) auf keinen Fall. Sie bitten nur darum, sich selbst zu verletzen, es gibt keinen Gewinn und Sie werden zu viele Ressourcen aufgeben.
Für High-End-Mikrocontroller (z. B. 32-Bit, 10 oder 100 MB für RAM und Speicher) mit einem anständigen Betriebssystem ist es vollkommen in Ordnung und, ich wage zu sagen, sogar zu empfehlen.
Die Frage ist also: Wo ist die Grenze?
Ich weiß es nicht genau, aber ich habe einmal ein System für ein 16-Bit-uC mit 1 MB RAM und 1 MB Speicher in C++ entwickelt, nur um es später zu bereuen. Ja, es hat funktioniert, aber die zusätzliche Arbeit, die ich hatte, war es nicht wert. Ich musste es passend machen, sicherstellen, dass Dinge wie Ausnahmen keine Lecks produzieren würden (der OS+RTL-Support war ziemlich fehlerhaft und unzuverlässig). Darüber hinaus führt eine OO-App normalerweise viele kleine Zuweisungen durch, und der Haufen Overhead für diese war ein weiterer Alptraum.
Angesichts dieser Erfahrung würde ich für zukünftige Projekte davon ausgehen, dass ich C++ nur in Systemen mit mindestens 16 Bit und mit mindestens 16 MB für RAM und Speicher wählen werde. Das ist eine willkürliche Grenze und wird wahrscheinlich je nach Art der Anwendung, Codierungsstilen und Redewendungen usw. variieren. Aber angesichts der Vorbehalte würde ich einen ähnlichen Ansatz empfehlen.
Es gibt einige Funktionen von C++, die in eingebetteten Systemen nützlich sind. Es gibt andere, wie Ausnahmen, die teuer sein können und deren Kosten nicht immer offensichtlich sind.
Wenn ich meine Brüder hätte, gäbe es eine populäre Sprache, die das Beste aus beiden Welten kombiniert und einige Merkmale enthält, die in beiden Sprachen fehlen; Einige Anbieter bieten einige solcher Funktionen an, aber es gibt keine Standards. Ein paar Dinge, die ich sehen möchte:
inline void copy_uint32s(uint32_t *dest, const uint32_t *src, __is_const int n) { wenn (n <= 0) zurück; sonst wenn (n == 1) {dest[0] = src[0];} Sonst wenn (n == 2) {dest[0] = src[0]; Ziel[1] = Quelle[1];} Sonst wenn (n == 3) {dest[0] = src[0]; Ziel[1] = Quelle[1]; Ziel[2] = Quelle[2];} Sonst wenn (n == 4) {dest[0] = src[0]; Ziel[1] = Quelle[1]; Ziel[2] = Quelle[2]; Ziel[3] = Quelle[3];} sonst memcpy((void*)dest, (const void*)src, n*sizeof(*src)); }Wenn 'n' zur Kompilierzeit ausgewertet werden kann, ist der obige Code effizienter als ein Aufruf von memcpy, aber wenn 'n' zur Kompilierzeit nicht ausgewertet werden kann, wäre der generierte Code viel größer und langsamer als Code, der einfach heißt memcpy.
Ich weiß, dass der Vater von C++ nicht allzu scharf auf eine reine Embedded-Version von C++ ist, aber ich würde denken, dass es einige erhebliche Verbesserungen gegenüber der Verwendung von C bieten könnte.
Weiß jemand, ob so etwas wie das oben Genannte für irgendeine Art von Standard in Betracht gezogen wird?
uint16_t x;
Anweisung x=(uint16_t)(x*x);
ein mod-65536-Ergebnis liefern muss, unabhängig vom Wert x
oder der Größe von int
. Obwohl der Standard nie irgendwelche Anforderungen gestellt hat, wenn die Größe von int
17 bis 32 Bit und x
46341 oder höher ist, verhalten sich 32-Bit-Compiler in solchen Fällen früher genauso wie 16-Bit-Compiler, aber heutzutage können sie sich auf seltsame und bizarre Weise verhalten.x=(uint16_t)(1u*x*x);
es besser wäre, den Code so zu schreiben, da selbst ein hypermoderner Compiler ihn nicht durcheinander bringen kann, sehe ich keine Möglichkeit, eine Sprachspezifikation zu verwenden, die nur Compiler erfordert sich konsequent verhalten, wenn die letztere Formulierung als "besser" angesehen werden sollte als eine, die vorschreibt, dass die erstere Formulierung die gleichen Ergebnisse liefern muss, wenn int
sie 17 bis 32 Bit beträgt, wie dies bei größeren oder kleineren int
Größen der Fall wäre.C++ ist mehr als eine Programmiersprache:
a) Es ist ein "besseres" C b) Es ist eine objektorientierte Sprache c) Es ist eine Sprache, die uns erlaubt, generische Programme zu schreiben
Obwohl alle diese Funktionen separat verwendet werden können, werden die besten Ergebnisse erzielt, wenn alle drei gleichzeitig verwendet werden. Wenn Sie sich jedoch entscheiden, nur eine davon auszuwählen, wird die Qualität der eingebetteten Software steigen.
a) Es ist ein "besseres" C
C++ ist eine stark typisierte Sprache; stärker als C. Ihre Programme werden von dieser Funktion profitieren.
Manche Leute haben Angst vor Pointern. C++ enthält die Referenzen. Überladene Funktionen.
Und erwähnenswert: Keines dieser Features tritt in größeren oder langsameren Programmen auf.
b) Es ist eine objektorientierte Sprache
Jemand hat in diesem Beitrag gesagt, dass es keine gute Idee ist, die Maschine in Mikrocontrollern zu abstrahieren. Falsch! Wir alle, die Embedded-Ingenieure, haben die Maschine immer abstrahiert, nur mit einer anderen Syntax als der von C++. Das Problem, das ich bei diesem Argument sehe, ist, dass einige Programmierer nicht daran gewöhnt sind, in Objekten zu denken, so dass sie die Vorteile von OOP nicht sehen.
Wann immer Sie bereit sind, das Peripheriegerät eines Mikrocontrollers zu verwenden, ist es wahrscheinlich, dass das Peripheriegerät für uns (von Ihnen oder einem Dritten) in Form des Gerätetreibers abstrahiert wurde. Wie ich bereits sagte, verwendet dieser Treiber die C-Syntax, wie das nächste Beispiel zeigt (direkt aus einem NXP LPC1114-Beispiel entnommen):
/* Timer-Setup für Match und Interrupt bei TICKRATE_HZ */
Chip_TIMER_Reset (LPC_TIMER32_0);
Chip_TIMER_MatchEnableInt (LPC_TIMER32_0, 1);
Chip_TIMER_SetMatch (LPC_TIMER32_0, 1, (timerFreq / TICKRATE_HZ2));
Chip_TIMER_ResetOnMatchEnable (LPC_TIMER32_0, 1);
Chip_TIMER_Enable (LPC_TIMER32_0);
Siehst du die Abstraktion? Wenn Sie also C++ für denselben Zweck verwenden, wird die Abstraktion durch den Abstraktions- und Kapselungsmechanismus von C++ zum Nulltarif auf die nächste Ebene gebracht!
c) Es ist eine Sprache, die es uns erlaubt, generische Programme zu schreiben
Generische Programme werden durch Vorlagen erreicht, und Vorlagen sind für unsere Programme ebenfalls kostenlos.
Außerdem wird statischer Polymorphismus mit Schablonen erreicht.
Virtuelle Methoden, RTTI und Ausnahmen.
Bei der Verwendung virtueller Methoden gibt es einen Kompromiss: bessere Software vs. Leistungseinbußen. Denken Sie jedoch daran, dass die dynamische Bindung wahrscheinlich mithilfe einer virtuellen Tabelle (einem Array von Funktionszeigern) implementiert wird. Ich habe das Gleiche oft in C gemacht (sogar regelmäßig), daher sehe ich keine Nachteile bei der Verwendung virtueller Methoden. Außerdem sind virtuelle Methoden in C++ eleganter.
Abschließend noch ein Ratschlag zu RTTI und Ausnahmen: VERWENDEN SIE SIE NICHT in eingebetteten Systemen. Vermeiden Sie sie um jeden Preis!!
Mein Hintergrund, eingebettet (MCU, PC, Unix, andere), Echtzeit. Sicherheitskritisch. Ich habe STL einem früheren Arbeitgeber vorgestellt. Das mache ich nicht mehr.
Einige Flame-Inhalte
Ist C++ für eingebettete Systeme geeignet?
Meh. C++ ist mühsam zu schreiben und mühsam zu warten. C+ ist irgendwie in Ordnung (benutze einige Funktionen nicht)
C++ in Mikrocontrollern? Echtzeitbetriebssysteme? Toaster? Embedded-PCs?
Wieder sage ich Meh. C+ ist nicht so schlimm, aber ADA ist weniger schmerzhaft (und das sagt wirklich etwas aus). Wenn Sie wie ich Glück haben, können Sie eingebettetes Java verwenden. Geprüfter Array-Zugriff und keine Zeigerarithmetik sorgen für sehr zuverlässigen Code. Garbage Collectors in Embedded Java haben nicht die höchste Priorität, und es gibt eine bereichsbezogene Wiederverwendung von Speicher und Objekten, sodass gut gestalteter Code für immer ohne GC ausgeführt werden kann.
Ist OOP auf Mikrocontrollern nützlich?
Sicher ist. Der UART ist ein Objekt..... Der DMAC ist ein Objekt...
Objektzustandsmaschinen sind sehr einfach.
Entfernt C++ den Programmierer zu weit von der Hardware, um effizient zu sein?
Wenn es sich nicht um einen PDP-11 handelt, ist C nicht Ihre CPU. C++ war ursprünglich ein Präprozessor auf C, also hörte Bjarne Stroustrup auf, ausgelacht zu werden, weil er bei AT&T langsame Simula-Simulationen hatte. C++ ist nicht deine CPU.
Holen Sie sich eine MCU, die Java-Bytecodes ausführt. Programm in Java. Lach über die C-Jungs.
Sollte Arduinos C++ (ohne dynamische Speicherverwaltung, Vorlagen, Ausnahmen) als "echtes C++" betrachtet werden?
Nö. genau wie alle bastardisierten C-Compiler da draußen für MCUs.
Forth, Embedded Java oder Embedded ADA sind standardisiert (ish); alles andere ist Leid.
<schimpfen>
Ich denke, C++ ist in erster Linie eine beschissene Sprache. Wenn Sie OOP verwenden möchten, schreiben Sie Java-Programme. C++ unternimmt nichts, um OOP-Paradigmen zu erzwingen, da der direkte Speicherzugriff vollständig in Ihrer Macht steht, ihn zu (missbrauchen) zu verwenden.
Wenn Sie eine MCU haben, sprechen Sie höchstwahrscheinlich von weniger als 100 KB Flash-Speicher. Sie möchten in einer Sprache programmieren, deren Abstraktion von Speicher ist: Wenn ich eine Variable oder ein Array deklariere, erhält sie Speicher, Punkt; malloc (auch bekannt als "new"-Schlüsselwort in C++) sollte mehr oder weniger von der Verwendung in eingebetteter Software ausgeschlossen werden, außer vielleicht in seltenen Fällen ein Aufruf während des Programmstarts.
Verdammt, es gibt (häufig) Zeiten in der Embedded-Programmierung, in denen C nicht ganz niedrig genug ist und Sie Dinge wie das Zuweisen von Variablen zu Registern und das Schreiben von Inline-Assembler tun müssen, um Ihre Interrupt-Service-Routinen (ISRs) zu straffen. Schlüsselwörter wie „flüchtig“ werden verdammt wichtig, um sie zu verstehen. Sie verbringen viel Zeit damit, Speicher auf Bitebene zu manipulieren , nicht auf Objektebene .
Warum sollten Sie sich der Illusion hingeben wollen, dass die Dinge einfacher sind, als sie tatsächlich sind?
</rant>
malloc (aka "new" keyword in C++) should be more or less banned from use in embedded software
--> Die zusätzliche Süße (Sarkasmus beabsichtigt) ist, dass new
Ausnahmen auch werfen können. Nun viel Glück damit.Eingebettete Systeme sind darauf ausgelegt, eine bestimmte Aufgabe zu erledigen, anstatt ein Allzweckcomputer für mehrere Aufgaben zu sein. Ein eingebettetes System ist eine Kombination aus Computerhardware und -software. C ist die Mutter aller modernen Sprachen. Es ist eine niedrige, aber leistungsstarke Sprache und behandelt alle Arten von Hardware. Daher ist C/C++ eine optimale Wahl für die Entwicklung von Software für eingebettete Systeme, die für jedes eingebettete System sehr nützlich ist. Wie wir wissen, ist C eine Entwicklungssprache. Das Betriebssystem UNIX ist in C geschrieben. Da es bei erfolgreicher Softwareentwicklung so häufig um die Auswahl der besten Sprache für ein bestimmtes Projekt geht, ist es überraschend festzustellen, dass sich die Sprache C/C++ sowohl für 8-Bit- als auch für 64-Bit-Prozessoren bewährt hat ; in Systemen mit Bytes, Kilobytes und Megabytes Speicher. C hat den Vorteil der Prozessorunabhängigkeit, Dadurch können sich Programmierer auf Algorithmen und Anwendungen konzentrieren, anstatt auf die Details einer bestimmten Prozessorarchitektur. Viele dieser Vorteile gelten jedoch gleichermaßen für andere Hochsprachen. Aber C/C++ war dort erfolgreich, wo so viele andere Sprachen weitgehend gescheitert sind?
J. Pölfer
Toby Jaffey
Kortuk
Vicatcu
Kortuk
Olin Lathrop
Kebs