Ist C ++ für eingebettete Systeme geeignet?


167

Eine häufige Frage, hier und anderswo. Ist C ++ für eingebettete Systeme geeignet?

Mikrocontroller? RTOSes? Toaster? Embedded-PCs?

Ist OOP für Mikrocontroller 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 wird dieses Wiki als Ort dienen, um diesen potenziellen heiligen Krieg einzudämmen.)


5
Kurze Frage: Wenn Sie Embedded sagen , meinen Sie damit Mikrocontroller? Mikroprozessor? Embedded x86 / Embedded PC?
J. Polfer

1
Ich hatte nicht vor, einen heiligen Krieg zu führen; Die Absicht war zu erfahren, was Ihre Argumente dagegen waren.
J. Polfer

2
Es ist in mehreren Fragen zuvor aufgetaucht, daher dachte ich, ein zentraler Ort wäre gut.
Toby Jaffey

4
C ++ vs. Embedded ist ein umstrittenes Thema. Ich habe eine starke Meinung, aber ich fand es nicht fair, eine Frage zu stellen und an den Punkten zu spielen. Ich hoffe, dass ein Community-Wiki für eine ausgewogenere Diskussion sorgt.
Toby Jaffey

13
Dies ist eine schlechte Frage, da "eingebettet" ein bedeutungsloses Attribut ist, um zu entscheiden, ob eine bestimmte Sprache und das zugehörige Gepäck geeignet sind. Der Punkt ist klein im Vergleich zu großen Systemen, auf denen kleine Systeme kein Betriebssystem ausführen, über begrenzten Arbeitsspeicher verfügen, möglicherweise nicht von-Neuman sind, möglicherweise verschiedene Hardwarebeschränkungen für Anrufstapel und Datenstapel gelten, und Sie können Mb nicht einfach dynamisch zuweisen oder sogar ein KB usw. Die meisten Mikrocontroller sind "kleine" Systeme. Einplatinencomputer sind normalerweise eingebettet, aber im Allgemeinen "große" Systeme.
Olin Lathrop

Antworten:


135

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 Nein-Nein wäre, obwohl es einen Compiler gibt und einige Leute es tun (schaudern). Es ist immer noch ein Vorteil, C ++ zu verwenden, auch wenn Sie es auf etwas wie "C +" verkleinern, selbst in einer 8-Bit-Mikrowelt. Was meine ich mit "C +"? Ich meine, verwende nicht new / delete, vermeide Ausnahmen, vermeide virtuelle Klassen mit Vererbung, vermeide möglicherweise die Vererbung insgesamt, gehe sehr vorsichtig mit Vorlagen um, verwende Inline-Funktionen anstelle von Makros und verwende constVariablen anstelle von #defines.

Ich arbeite seit mehr als einem Jahrzehnt sowohl in C als auch in C ++ in eingebetteten Systemen, und ein Teil meiner jugendlichen Begeisterung für C ++ hat sich definitiv aufgrund einiger Probleme in der realen Welt gelegt, die die Naivität erschüttern. Ich habe das Schlimmste von C ++ in eingebetteten Systemen gesehen, die ich als "CS-Programmierer, die in einer EE-Welt verrückt geworden sind" bezeichnen möchte. Tatsächlich arbeite ich mit meinem Kunden daran, diese eine Codebasis zu verbessern, die sie unter anderem haben.

Die Gefahr von C ++ besteht darin, dass es ein sehr leistungsfähiges Werkzeug ist, das einem zweischneidigen Schwert ähnelt, das Ihnen sowohl den Arm als auch das Bein abschneiden kann, wenn es nicht in der Sprache und der allgemeinen Programmierung selbst geschult und diszipliniert ist. C ist eher ein einschneidiges Schwert, aber immer noch genauso scharf. Mit C ++ ist es zu einfach, sehr hohe Abstraktionsebenen zu erhalten und verschleierte Schnittstellen zu erstellen, die langfristig bedeutungslos werden. Dies liegt zum Teil an der Flexibilität von C ++ bei der Lösung desselben Problems mit vielen verschiedenen Sprachfunktionen (Vorlagen, OOP, prozedural, RTTI, OOP + -Vorlagen, Überladen, Inlining).

Ich beendete zwei 4-stündige Seminare über eingebettete Software in C ++ durch den C ++ - Guru Scott Meyers. Er wies auf einige Dinge über Vorlagen hin, die ich noch nie in Betracht gezogen hatte, und wie viel mehr sie beim Erstellen von sicherheitskritischem Code helfen können. Der Clou dabei ist, dass in Software kein toter Code enthalten sein darf, der strengen sicherheitskritischen Code-Anforderungen genügen muss. Vorlagen können Ihnen dabei helfen, da der Compiler nur den Code erstellt, den er zum Instanziieren von Vorlagen benötigt. Man muss sich jedoch gründlicher damit auskennen, um dieses Feature korrekt zu entwerfen, was in C schwieriger zu bewerkstelligen ist, da Linker nicht immer toten Code optimieren.

Scott Meyers ist ein sehr großer Befürworter von Vorlagen und einer vernünftigen Verwendung von Inlining, und ich muss sagen, dass ich immer noch skeptisch bin, wenn es um Vorlagen geht. Ich neige dazu, sie zu scheuen, obwohl er sagt, sie sollten nur dort angewendet werden, wo sie das beste Werkzeug sind. Er macht auch darauf aufmerksam, dass C ++ Ihnen die Werkzeuge zur Verfügung stellt, um wirklich gute Schnittstellen zu erstellen, die einfach zu verwenden sind und die es schwierig machen, falsch zu verwenden. Auch das ist der schwierige Teil. In C ++ muss eine gewisse Beherrschung erreicht werden, bevor Sie wissen, wie Sie diese Funktionen am effizientesten anwenden können, um die beste Entwurfslösung zu erhalten.

Gleiches gilt für OOP. In der eingebetteten Welt müssen Sie sich mit der Art des Codes vertraut machen, den der Compiler ausgibt, um zu wissen, ob Sie die Laufzeitkosten des Laufzeitpolymorphismus bewältigen können. Sie müssen auch bereit sein, Messungen durchzuführen, um zu beweisen, dass Ihr Design Ihre Terminanforderungen erfüllen wird. Wird diese neue InterruptManager-Klasse meine Interrupt-Latenz zu lang machen? Es gibt andere Formen des Polymorphismus, die möglicherweise besser zu Ihrem Problem passen, z. B. den Link-Time-Polymorphismus, den C ebenfalls kann, C ++ jedoch über das Pimpl-Entwurfsmuster (undurchsichtiger Zeiger). .

Ich sage das alles um zu sagen, dass C ++ seinen Platz in der Embedded-Welt hat. Sie können es hassen, was Sie wollen, aber es geht nicht weg. Es kann sehr effizient geschrieben werden, aber es ist schwieriger zu lernen, wie man es richtig macht als mit C. Es kann manchmal besser funktionieren als C, um ein Problem zu lösen und manchmal eine bessere Oberfläche auszudrücken, aber man muss es auch tun Erziehe dich selbst und habe keine Angst zu lernen, wie.


1
Dies stimmt mit dem überein, was ich von anderen Beratern für eingebettete Systeme gelesen habe. Mir wurde immer beigebracht, dass man sich mit C ständig ein Stückchen abschneidet, aber ein Fehler in C ++ wird seltener sein, aber wenn man es vermasselt, verliert man ein Bein. Vielen Dank, dass Sie eine klare Antwort mit etwas Fachwissen geschrieben haben, über das ich nicht verfüge.
Kortuk

3
Auf dem Zettel der Informatik-Majors, die im EE-Land verrückt werden. Bei meiner Arbeit wurde das schlechteste Stück Code, das wir haben, von einem CS-Major geschrieben. Wir haben ewig versucht, ihm die Hardware beizubringen. Er erstellte ein strukturiertes System mit UML und baute das gesamte System unter Verwendung der richtigen Vererbung und so weiter in Java auf. Es hat funktioniert, bis sich etwas geändert hat, und dann war es ein schlechter Patch-Job, Features hinzuzufügen oder ein vollständiges Redesign. Der Code ist fast nicht verwendbar, da er das Ganze gründlich mit Vererbung verschleiert hat.
Kortuk

2
Es sind nicht nur Bugs, die dich beißen, sondern auch Code, der nicht mehr zu pflegen ist. Sicher, wenn Sie dieses Projekt mit diesen netten C ++ - Funktionen starten, läuft alles reibungslos, aber nach 2 oder 3 Jahren setzt die Entropie ein, wenn bei der Entwicklung keine ernsthaften Anstrengungen unternommen werden. Das ist es, womit ich gerade konfrontiert bin. In C ++ rotiert der Code mit der Zeit schneller.
Jay Atkinson

2
UML und Statemachines. Auf state-machine.com muss man sich unbedingt mit Miro Sameks Sachen beschäftigen . Er hat ein effizientes System aufgebaut, das leicht umzugestalten und zu ändern ist, aber es braucht einige Zeit, um es in den Griff zu bekommen.
Jay Atkinson

2
Es hängt wirklich von Ihrem System ab und davon, wie viel Speicher Sie zur Verfügung haben. Schreiben Sie Code auf einem 8-Bit-Mikro mit sehr wenig RAM? Dann ist es vielleicht besser, wenn Sie vermeiden, dass Sie an abstrakten Schnittstellen verrückt werden. Wenn Sie so etwas wie eingebettete 32-Bit-Systeme mit wenig Arbeitsspeicher schreiben, sollten Sie sich dafür entscheiden. Man muss es wirklich abwägen. Beispielsweise erhalten Sie jedes Mal, wenn Sie die Welt "virtuell" auf diese Klasse setzen, einen zusätzlichen Zeiger, der je nach System 8-Bit, 16-Bit oder 32-Bit sein kann, für jede einzelne Instanz, die Sie für dieses Objekt deklarieren. Sie werden nicht einmal erkennen, und Mann,
Jay Atkinson

56

C ++ ist absolut geeignet für eingebettete Systeme. Ich benutze jetzt das Vorhandensein / Fehlen von guten Entwicklungswerkzeugen (oder das Fehlen von solchen) als mein primäres Kriterium dafür, ob ein bestimmter Mikroprozessor verwendet werden soll oder nicht.

Bereiche von C ++, die sich aufgrund ihrer geringen Ressourcenkosten gut für eingebettete Systeme eignen:

  • Modularität durch gute Nutzung von Klassen / Strukturen
  • Vorlagen, wenn der Compiler diese effizient kompiliert. Vorlagen sind ein gutes Werkzeug, um die Wiederverwendung von Algorithmen auf verschiedene Datentypen zu übertragen.

OK Bereiche:

  • Virtuelle Funktionen - Früher war ich dagegen, aber die Ressourcenkosten sind sehr gering (eine V-Tabelle pro Klasse , nicht pro Objekt; ein Zeiger auf die V-Tabelle pro Objekt; eine Dereferenzierungsoperation pro virtuellen Funktionsaufruf) und der große Vorteil davon Das bedeutet, dass Sie ein Array mit mehreren verschiedenen Objekttypen haben können, ohne dass Sie wissen müssen, um welchen Typ es sich handelt. Ich habe dies kürzlich verwendet, um ein Array von Objekten zu haben, die jeweils ein I2C-Gerät darstellen, jedes mit separaten Methoden.

Nicht zu verwendende Bereiche, vor allem aufgrund des auf kleinen Systemen nicht akzeptablen Laufzeitaufwands:

  • dynamische Speicherzuweisung - andere haben dies erwähnt, ein weiterer wichtiger Grund jedoch nicht , die dynamische Speicherzuweisung zu verwenden, besteht darin, dass dies eine Unsicherheit im Timing darstellt; Viele Gründe für die Verwendung eingebetteter Systeme sind für Echtzeitanwendungen.
  • RTTI (Runtime Type Information) - Die Speicherkosten sind ziemlich hoch
  • Ausnahmen - ein definitives Nein-Nein, aufgrund des Treffers der Ausführungsgeschwindigkeit

Danke für die Eingabe. Interessant und sehr ähnlich zu dem, was ich gelesen habe.
Kortuk,

1
Tatsächlich ist die dynamische Speicherzuweisung in Ordnung und manchmal unvermeidbar. Das Problem ist die dynamische Speicherzuordnung (und die anschließende Wiederverwendung). RTTI ist Memory Hog, da stimme ich zu. Aber wo liegt das Problem mit Ausnahmen?
Wouter van Ooijen

1
@WoutervanOoijen: Das Problem mit Ausnahmen besteht darin, dass beim fooAufrufen barinnerhalb eines try/ catch-Blocks und beim barErstellen einiger Objekte und Aufrufe boz, die eine Ausnahme auslösen , das System die Destruktoren für die barerstellten Objekte irgendwie aufrufen muss, bevor die Steuerung an zurückgegeben wird foo. Sofern Ausnahmen nicht vollständig deaktiviert sind, barhaben Sie keine Möglichkeit zu wissen, ob bozsie ausgelöst werden könnten, und müssen daher zusätzlichen Code enthalten, um diese Möglichkeit zu ermöglichen. Ich würde gerne eine Variation von C ++ mit "geprüften Ausnahmen" sehen, um das zu lösen. Wenn Routinen, die Ausnahmen zu entkommen ermöglichen könnten ...
Supercat

1
... als solche deklariert werden müssten, dann müsste der Compiler nur noch Exception-Handling-Code in die Aufrufer solcher Routinen einbinden. Es wäre zwar etwas mühsam, alle erforderlichen Erklärungen hinzufügen zu müssen, aber hoffentlich unnötige zu vermeiden, aber es würde ermöglichen, Ausnahmen an Orten zu verwenden, an denen sie nützlich sind, ohne zusätzlichen Aufwand, an denen sie nicht erforderlich sind.
Supercat

3
@WoutervanOoijen: Übrigens, wenn ich das ABI für eine solche Ausnahmebehandlung auf dem ARM entwerfen würde, würde ich den Code angeben, der eine Routine aufruft, die über eine Ausnahme beendet werden kann. R14 sollte auf eine Adresse zwei Bytes vor der gewünschten Rücksprungadresse zeigen (dies würde natürlich auftreten, wenn der Aufrufer der Anweisung CALL mit einem 16-Bit-Wort gefolgt ist). Die aufgerufene Routine würde dann normal über add r15,r14,#2beenden mov r15,r14; über Ausnahme, zu verlassen ldrhs r0,[r14] / add r15,r14,r0. Keine Zykluskosten für den normalen Ausgang und keine Einschränkungen für Stapelrahmen.
Supercat

36

Ja, C ++ ist auf jeden Fall für eingebettete Systeme geeignet. Lassen Sie uns zunächst einige Missverständnisse über den Unterschied zwischen C und C ++ aufklären:

In einem eingebetteten Mikro müssen Sie immer sorgfältig Hochsprachen verwenden, wenn Sie Zeit- oder Raumbeschränkungen befürchten. Beispielsweise verarbeiten viele MCUs Zeiger nicht gut und sind daher bei der Verwendung des Stapels sehr ineffizient. Dies bedeutet, dass Sie vorsichtig sein müssen, wenn Sie Variablen mithilfe von Arrays und Zeigern und Rekursion an Funktionen übergeben. Eine einfache Zeile von C wie:

a[i] = b[j] * c[k];

kann in Abhängigkeit von der Art dieser Variablen ungefähr 4 Seiten mit Anweisungen generieren.

Wenn Sie eine höhere Sprache verwenden und Zeit- und Raumprobleme haben, müssen Sie wissen, wie sich jede Funktion dieser Sprache in Maschinenanweisungen auf Ihrer MCU umsetzt (zumindest jede Funktion, die Sie verwenden). Dies 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 keine 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.

Hier ist der Grund, warum ich denke, dass C ++ sogar auf 8-Bit-MCUs besser ist als C: C ++ bietet verbesserte Unterstützung für:

  • Daten verstecken
  • Stärkeres Tippen / Prüfen
  • Transparenz über mehrere Peripheriegeräte mithilfe von Klassen
  • Vorlagen (wie immer bei sorgfältiger Verwendung)
  • Initialisierungslisten
  • const

Keines dieser Merkmale ist schwerer als die typischen Merkmale von C.

Wenn Sie bis zu 16- oder 32-Bit-MCUs verschieben, ist es sinnvoll, die umfangreicheren Funktionen von C (Stapel, Heap, Zeiger, Arrays, PrintF usw.) zu verwenden. Auf die gleiche Weise eignet sich eine leistungsstärkere MCU schwerere Funktionen von C ++ zu verwenden (Stack, Heap, Referenzen, AWL, neu / löschen).

Der Gedanke an C ++ auf einem PIC16 muss also nicht erschaudern. Wenn Sie Ihre Sprache und Ihre MCU richtig kennen, wissen Sie, wie Sie beide effektiv zusammen einsetzen können.


3
Dies ist eine sehr gut formulierte und vernünftige Antwort auf die Frage. +1 Prost!
Vicatcu

1
" a[i] = b[j] * c[k];Kann in Abhängigkeit von der Art dieser Variablen ungefähr 4 Seiten mit Anweisungen erzeugen." Wenn Ihr MCU / Compiler dies tut, liegt es daran, dass Sie eine Werkstatt-Hobby-CPU aus den 80ern verwenden.
Lundin

@Lundin - Seufz. Nein, es bedeutet, dass Sie eine billige kleine MCU verwenden, die so klein und billig wie möglich ist und keine komplexen Dinge wie die Stapelindizierung enthält.
Rocketmagnet

2
@Rocketmagnet Ok, vielleicht in den 1990ern? Heutzutage gibt es beschissene 8 Bitter zum gleichen Preis wie 32 Bitter. Einziger Grund für die Auswahl des ersteren ist der aktuelle Verbrauch. Und in Bezug auf diese extrem beschissenen 8-Bitter ohne Stack: Wenn Sie für eine so begrenzte MCU C anstelle von Assembler schreiben, machen Sie es wahrscheinlich falsch. Die 4 erzeugten Seiten sind dann Ihre eigene Schuld, wenn Sie zu komplexe Programme für die CPU schreiben, und im Grunde ist C das falsche Werkzeug für die Aufgabe. (Ich habe dies in der Vergangenheit auf Freescale RS08 gemacht, es war eine sehr dumme Idee.)
Lundin

@Lundin 32-Bit-Prozessor ist nicht schneller als 16-Bit erforderlich. Dies war schon vor langer Zeit zu beobachten, als in der PC-Welt ein Programmwechsel von 16 auf 32 Bit stattfand.
Barleyman

24

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 Einstellung eines Menschen zum Thema auf der Grundlage seines Jobs / seiner Erfahrung / seines Interessengebiets festlegen können. Es stimmt mit den Argumenten der "vorzeitigen Optimierung" überein, dass die CS-Majors und Wartungsprogrammierer Knuth links und rechts zitieren, und diejenigen, die in der realen Welt arbeiten, in der es auf die Leistung ankommt, denken, sie seien alle verrückt (ich bin ein Mitglied der letzteren Gruppe) um fair zu sein).

Letztendlich können Sie hier exzellente 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 dann erforderlich, wenn Sie die falsche Sprache ausgewählt haben und diese nun zur Lösung Ihres Problems verwenden müssen. In den meisten Fällen sind dies die einzigen Situationen, in denen Sie sich mit undurchsichtigen Funktionen oder Compilern auseinandersetzen müssen Tricks, um das Ziel zu erreichen.

Ich höre oft Leute, die diese Argumente als "Ich bin ein Experte in Sprache X und bla bla" anfangen. Ich diskreditiere diese Leute ehrlich gesagt sofort, weil sie meiner Meinung nach das Problem bereits aus dem falschen Blickwinkel angegangen sind und alles danach verdorben ist durch ihren Wunsch, mit ihrem Werkzeug 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 Mistlösungen führt.

Wie ich in einem Kommentar zu einer anderen Antwort erwähnt habe, wird in diesen Sprachkriegen oft argumentiert, dass die Sprache X dem Programmierer erlaubt, mehr dumme Dinge zu tun. Während das Lesen unterhaltsam ist, bedeuten all diese Aussagen, dass Sie ein Problem damit haben, gute Entwickler einzustellen und dieses Problem direkt angehen müssen, anstatt zu versuchen, die Situation zu verbessern, indem Sie weiterhin schlechte Entwickler einstellen und Tools auswählen, die so wenig wie möglich leisten Schaden wie möglich.

Meiner Meinung nach sind gute Entwickler, sei es Software- oder Hardware-Entwicklung, recherchieren das Problem, entwickeln 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 benötigte Tool etwas ist, das Sie noch nie zuvor verwendet haben. Nachdem Sie 3-4 Sprachen / Entwicklungstools für Projekte verwendet haben, die ein neues Tool aufnehmen, sollte dies nur minimale Auswirkungen auf Ihre Entwicklungszeit haben.

Natürlich ist 'bester Weg' ein subjektiver Begriff und muss auch in der Forschungsphase definiert werden. Man muss eine Vielzahl von Aspekten berücksichtigen: Leistung, einfache Ausdrucksweise, Codedichte usw., basierend auf dem vorliegenden Problem. Ich habe die Wartbarkeit aus einem bestimmten Grund nicht in diese Liste aufgenommen. Es ist mir egal, welche Sprache Sie auswählen, wenn Sie das richtige Tool ausgewählt und sich die Zeit genommen haben, um das Problem zu verstehen, das "kostenlos" auftreten sollte. Schwierig zu pflegender Code ist oft das Ergebnis der Wahl des falschen Tools oder einer schlechten Systemstruktur. Dies führt zu einem hässlichen Durcheinander, damit es funktioniert.

Die Behauptung, dass eine Sprache besser ist als jede andere, ist dumm, 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 Designparadigma eignen. Es gibt viele, die dies nicht tun. Dieselbe Aussage kann über viele Sprachmerkmale gemacht werden, auf denen die Leute gerne zu harpen scheinen.

Wenn Sie mehr als 20% Ihrer Zeit mit dem eigentlichen Eingeben von Code verbringen, produzieren Sie wahrscheinlich ein sehr schlechtes System oder haben sehr schlechte Entwickler (oder Sie lernen noch). Sie sollten die meiste Zeit im Voraus damit verbringen, das Problem zu beschreiben und zu bestimmen, wie die verschiedenen Teile der Anwendung interagieren. Wenn Sie eine Gruppe talentierter Entwickler in einen Raum mit einem Markierungsfeld und einem zu lösenden Problem stecken und ihnen mitteilen, dass sie keinen Code schreiben oder Werkzeuge auswählen dürfen, bis sie sich mit dem gesamten System vertraut fühlen, wird dies die Qualität des verbessern Leistung und Geschwindigkeit der Entwicklung als bei der Auswahl eines neuen Tools, das die Entwicklungszeit garantiert verkürzt. (Scrum Development als Referenz für das Gegenteil meiner Argumentation nachschlagen)

Leider können viele Unternehmen den Wert eines Entwicklers nur anhand der Anzahl der geschriebenen Zeilen oder anhand der "greifbaren Ausgabe" messen. Sie betrachten die 3 Wochen in einem Raum mit einer Markierungstafel als Produktivitätsverlust. Entwickler sind oft gezwungen, die "Gedanken" -Entwicklungsphase zu durchlaufen, oder sind gezwungen, ein Tool zu verwenden, das durch ein politisches Problem innerhalb des Unternehmens festgelegt wurde: "Der Bruder meines Chefs arbeitet für IBM, damit wir nur ihre Tools verwenden können." . Oder schlimmer noch, Sie bekommen ständig wechselnde Anforderungen vom Unternehmen, weil sie keine ordnungsgemäße Marktforschung durchführen können oder die Auswirkungen von Änderungen auf den Entwicklungszyklus nicht verstehen.

Es tut mir leid, dass ich mit diesem Geschwätz ein wenig vom Thema abkam. Ich habe ziemlich starke Meinungen zu diesem Thema.


2
Jetzt kann ich auf bestimmten Embedded-Systemen keine Unit-Tests auf Anwendungsebene (über dem Treiber) durchführen. Das sofortige Feedback von Unit-Tests und der Beseitigung von Fehlern zu Beginn der Entwicklungsphase hat einen gewissen Wert, aber das gesamte TDD-Paradigma, um das Design hervorzubringen, scheint mir ein wenig verblüffend. Ich nehme mir lieber etwas Zeit, um über das Problem nachzudenken und es entweder in meinem Kopf, auf Papier oder auf einem Whiteboard darzustellen, bevor ich mit dem Code beginne. Ich denke auch, dass TDD den Markt dazu ermutigt, keine Vorausforschungen über Anforderungen anzustellen, da dies bei ständigen Änderungen der Anforderungen helfen soll.
Jay Atkinson

2
Und um einen letzten Hinweis auf meinen super langen Kommentar zu geben. Wir brauchen keine Sprachexperten, um das Design zu bearbeiten. Wir brauchen erfahrene Designer, die die Sprache (n) bearbeiten können.
Jay Atkinson

1
PRD = Produktanforderungsdokument, MRD = Marketinganforderungsdokument, TRD = technisches Anforderungsdokument. TDD = Test Driven Development.
Jay Atkinson

1
@Mark - Ich stimme Ihren Vorstellungen zum Design zu, aber nur bis zu einem gewissen Punkt. Ich denke, schwere Design-Up-Front-Arbeiten zahlen sich aus, wenn a) Ihre Anforderungen ziemlich stabil / bekannt sind und b) die Entwickler, die das Design entwickeln, Erfahrung haben . In einem vorh. Ich hatte die Aufgabe, ein Design zu entwerfen, und mein Teamleiter hatte viel Zeit dafür, und ich dachte: "Was für eine blöde Sache! Design im Voraus spart Geld (vgl. Code Complete-Buch)?" Aber beim Codieren entdeckte ich Unmengen von Dingen, nach denen ich nicht suchen konnte. Wenn ich viel Design gemacht und die Codezeit minimiert hätte, wäre es eine Verschwendung gewesen. JME.
J. Polfer

1
@sheepsimulator Ich stimme natürlich dem zweiten Punkt zu, ich gehe davon aus, dass die leitenden Systemarchitekten erfahrene Entwickler sind. Im ersten Punkt bin ich nicht einverstanden. Ich denke, je mehr Sie erwarten, dass sich die Anforderungen ändern, desto mehr Zeit sollten Sie in der Designphase aufwenden, da Sie ein gutes, einfach zu änderndes Design erstellen müssen. Ich weiß, dass einige Philosophien eine rasche Entwicklung vorschlagen. In einigen Fällen funktioniert dies gut, wenn viele schlechte oder unerfahrene Programmierer im Personal sind. All diese Designphilosophien lauten: "Ich habe kein Gebet, ein flexibles System zu entwerfen, also lasst uns keine Zeit damit verschwenden, es zu versuchen."
Mark

17

Jede Sprache kann für ein eingebettetes System geeignet sein. Eingebettet heißt nur: Teil eines größeren Geräts im Gegensatz zu einem frei verwendbaren Computer.

Die Frage ist relevanter, wenn nach einem (harten) Echtzeitsystem oder einem System mit begrenzten Ressourcen gefragt wird.

Für ein Echtzeitsystem ist C ++ eine der höchsten Sprachen, die beim Programmieren unter Berücksichtigung strenger Zeitbeschränkungen immer noch angemessen ist. Mit Ausnahme der Verwendung von Heap (freier Operator) gibt es keine Konstrukte mit einer unbestimmten Ausführungszeit. Sie können also testen, ob Ihr Programm die Timing-Anforderungen erfüllt, und mit etwas mehr Erfahrung können Sie es sogar vorhersagen. Die Verwendung von Heap sollte natürlich vermieden werden, obwohl der neue Operator weiterhin für die einmalige Zuweisung verwendet werden kann. Die Konstrukte, die C ++ über C anbietet, können in einem eingebetteten System sinnvoll eingesetzt werden: OO, Ausnahmen, Vorlagen.

Für sehr ressourcenbeschränkte Systeme (8-Bit-Chips, weniger als ein paar KB RAM, kein verfügbarer Stapel) ist volles C ++ möglicherweise ungeeignet, obwohl es immer noch als "besseres C" verwendet werden kann.

Ich finde es bedauerlich, dass Ada nur in einigen Nischen eingesetzt zu werden scheint. In vielerlei Hinsicht ist es ein Pascal ++, aber ohne die Last, mit einer Sprache aufwärtskompatibel zu sein, die anfangs schon ein ernstes Durcheinander war. (redigieren Sie: das ernste 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 unter Bezugnahme auf diese geschlossen wurde. Deshalb werde ich hinzufügen, was ich geschrieben habe:

Es gibt nie einen ausschlaggebenden 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, mit Positionen, die von "Verwenden Sie niemals C ++ für einen Mikrocontroller" bis "Verwenden Sie immer C ++" reichen. Ich bin mehr mit der letzten Position. Ich kann einige Argumente anführen, aber Sie müssen selbst entscheiden, wie viel Gewicht sie in einer bestimmten Situation (und in welche Richtung) haben.

  • C ++ - Compiler sind seltener als C-Compiler. Für einige Ziele (z. B. 12- und 14-Bit-Core-PICs) gibt es überhaupt keine C ++ - Compiler.
  • (gute) C ++ - Programmierer sind seltener als (gute) C-Programmierer, insbesondere unter denjenigen, die sich auch (etwas) mit Elektronik auskennen.
  • C ++ hat mehr Konstrukte als C, die für kleine Systeme nicht geeignet sind (wie Ausnahmen, RTTI, häufige Verwendung des Heapspeichers).
  • C ++ hat eine größere Anzahl von (Standard-) Bibliotheken als C, aber eine Konsequenz des vorherigen Punkts ist, dass C ++ - Bibliotheken häufig Funktionen verwenden, die für kleine Systeme ungeeignet und daher auf kleinen Systemen nicht benutzbar sind.
  • C ++ hat mehr Konstrukte als C, mit denen Sie sich in den Fuß schießen können.
  • C ++ hat mehr Konstrukte als C, mit denen Sie verhindern können , dass Sie sich in den Fuß schießen (ja, IMO, dies und das vorherige sind beide wahr).
  • C ++ verfügt über eine größere Anzahl von Abstraktionsmechanismen, sodass insbesondere für Bibliotheken bessere Programmiermöglichkeiten zur Verfügung stehen.
  • C ++ - Sprachfunktionen (z. B. Konstruktoren / Destruktoren, Konvertierungsfunktionen) erschweren es, den Code zu durchschauen, um die generierte Maschine und damit die Kosten für Raum und Zeit eines Sprachkonstrukts zu ermitteln.
  • C ++ - Sprachkonstrukte machen es weniger notwendig, sich darüber im Klaren zu sein, wie genau sie in Maschinencode übersetzt werden, da sie abstrakter das Richtige tun.
  • Der C ++ - Sprachstandard entwickelt sich schnell und wird von den großen Compilern (gcc, clang, microsoft) schnell übernommen. C entwickelt sich eher langsam, und die Übernahme einiger neuer Funktionen (Variantenarrays) ist erschreckend und wurde in einem späteren Standard sogar rückgängig gemacht. Dieser Punkt ist insbesondere deshalb interessant, weil verschiedene Leute ihn verwenden, um die entgegengesetzten Positionen zu unterstützen.
  • C ++ ist zweifellos ein schärferes Werkzeug als C. Vertrauen Sie Ihren Programmierern (oder sich selbst), ein solches Werkzeug zu verwenden, um eine schöne Skulptur zu erstellen, oder befürchten Sie, dass sie sich selbst verletzen, und geben Sie sich lieber mit einem weniger schönen Produkt mit geringerem Risiko zufrieden ? (Ich erinnere mich , dass meine Skulptur Lehrer haben mir einmal erzählt , dass stumpfe Werkzeuge in einigen Situationen sein können mehr gefährlicher als scharf diejenigen.)

Mein Blog enthält einige Schriften zur Verwendung von C ++ auf kleinen Systemen (= Mikrocontrollern).


15

Nach meiner Erfahrung eignet sich C ++ normalerweise nicht für kleine eingebettete Systeme. Damit meine ich Mikrocontroller und Geräte ohne Betriebssystem.

Viele C ++ - OOP-Techniken basieren auf der dynamischen Speicherzuweisung. Dies fehlt häufig in kleinen Systemen.

STL und Boost demonstrieren die Leistungsfähigkeit von C ++, beide haben eine enorme Stellfläche.

C ++ ermutigt den Programmierer, die Maschine zu abstrahieren, wo sie in eingeschränkten Systemen berücksichtigt 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. Es stützte sich jedoch stark auf STL, dynamischen Speicher und C ++ - Ausnahmen. Um es in WinCE-, Symbian- und OS-freien Umgebungen zum Laufen zu bringen, war ein C-Rewrite die vernünftigste Option.


Ich stimme in Bezug auf kleine Systeme zu, aber ich denke, wir haben unterschiedliche Definitionen von kleinen Systemen. Wenn Sie 1 KB ROM haben und gut geschriebener C-Code bis auf 1 Byte ROM benötigt, ist das ein kleines System.
Kortuk

6
Ich behaupte nicht, dass C keinen kleineren Footprint haben kann, aber Sie hätten C ++ trotzdem verwenden und ein sehr ähnliches Ergebnis für das Entwerfen für das erhalten können, was gerade besprochen wurde. Ich denke, das Problem ist, dass die meisten OOP-Programmierer an Systeme mit dynamischem Speicher gewöhnt sind und sehr ineffiziente Konstrukte verwenden, was zu völlig nutzlosem Code für Systeme mit geringerer Leistung führt.
Kortuk

4
Wenn Sie also nicht C ++ verwenden möchten, möchten Sie etwas zwischen C und C ++ verwenden (nennen wir es einfach C +?). In diesem Fall stimme ich zu, es gibt eine Menge Mist in C ++, den die Leute verwenden, nur weil er verfügbar ist, nicht weil er optimal ist. Nahezu jede Sprache ist in der Lage, guten, schnellen Code zu erstellen, je nachdem, wie er verwendet wird. Die meisten heiligen Kriege über Sprachen sind kein Ergebnis der Sprachen Fähigkeiten , sondern ein Streit darüber , wie leicht es für einen Idiot ist idiotisch , Dinge zu tun, die wirklich ein idiotisches Argument ist: p
Mark

2
"Die meisten heiligen Kriege um Sprachen sind nicht das Ergebnis der Sprachfähigkeiten, sondern ein Streit darüber, wie einfach es für einen Idioten ist, idiotische Dinge zu tun, was wirklich ein idiotisches Argument ist." War ein sehr schöner Satz. Ich brauche deinen Nachnamen, damit ich ihn zitieren kann.
Kortuk

1
Ich benutze den dynamischen Speicher aber auch nicht in C. Es gibt keinen Ort, an dem ich es haben muss. Langfristig habe ich gelesen, dass es sehr sehr segmentiert werden und anfangen kann, Probleme zu verursachen. Ich brauche sehr klar gestaltete Fälle, um nicht genügend Arbeitsspeicher zur Verfügung zu haben, und ich muss in der Lage sein, genau zu überwachen, wie viel noch übrig ist.
Kortuk

11

Ich hoffe, diese Diskussion über C ++ auf Bare-Metal- und ressourcenbeschränkten Systemen mit mehr Licht als Wärme zu füllen.

Probleme in C ++:

  • Ausnahmen sind insbesondere ein RAM-Problem, da der erforderliche "Notfallpuffer" (bei dem beispielsweise die Ausnahme "Nicht genügend Arbeitsspeicher" auftritt) größer sein kann als der verfügbare RAM und sicherlich eine Verschwendung für Mikrocontroller darstellt. Weitere Informationen finden Sie unter n4049 und n4234 . Sie sollten ausgeschaltet sein (was derzeit kein bestimmtes Verhalten ist, also seien Sie sicher und werfen Sie niemals). SG14 arbeitet derzeit an besseren Wegen, dies zu tun.

  • RTTI ist wahrscheinlich nie den Aufwand wert, es sollte ausgeschaltet sein

  • 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 entsteht durch Vorlagencode oder zusätzliche Funktionsaufrufe, 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. Bei Debug-Builds kann dies jedoch ein Problem sein.

  • Heap-Zuordnung. Obwohl die AWL die Verwendung von benutzerdefinierten Zuweisern zulässt, kann dies für die meisten Programmierer komplex sein. Die Heap-Zuweisung ist nicht deterministisch (dh keine harte Echtzeit) und Fragmentierung kann zu unerwarteten Situationen außerhalb des Arbeitsspeichers führen, die auftreten können, obwohl sie beim Testen gearbeitet haben. Die Buchhaltung, die der Haufen benötigt, um den freien Speicherplatz und die unterschiedliche Größe im Auge zu behalten, kann bei kleinen Objekten ein Problem sein. Normalerweise ist es besser, die Poolzuordnung zu verwenden (sowohl in C als auch in C ++), aber dies kann für C ++ - Programmierer, die nur den Heap verwenden, ungewöhnlich sein.

  • Laufzeit-Polymorphismus und andere indirekte Aufrufe sind in der Regel ein großer Leistungseinbruch. Das Problem liegt in der Regel darin, dass der Optimierer sie nicht mehr durchschauen kann als das eigentliche Abrufen und Springen zur Adresse. Indirekte Aufrufe sind aus diesem Grund in C und C ++ zu vermeiden, wo sie wie in C ++ stärker in der Kultur verankert sind (und in anderen Bereichen durchaus nützlich sind).

  • Eine implizite Verbindung mit clib kann problematisch sein. Es mag unerklärlich sein, dass Clib-Probleme in der Kategorie C ++ liegen, 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 allgemeinen newLib-Implementierung führt häufig zu viel Aufblähung, die in der Regel in uCs nicht benötigt wird. Andererseits ist newLibNanno nicht wiedereintrittsfähig, sodass der Zugriff darauf serialisiert werden muss (hier zu stark vereinfacht). Dies ist auch für C ein Problem, aber der Zugriff ist expliziter. Als Faustregel sollte man im ISR-Kontext im Wesentlichen nichts aus dem Namespace std verwenden, es sei denn, Sie sind sicher, dass es nicht irgendwie auf den Status in clib zugreift (z. B. errorno oder der Heap). Es ist auch wichtig, wenn Sie Threads verwenden (ich bevorzuge RTC), um new zu überschreiben und delete, um den Zugriff auf malloc und free zu synchronisieren.

Zusammenfassend lässt sich sagen, dass C ++ einige Probleme aufweist, die jedoch im Wesentlichen alle behoben oder vermieden werden können.

Jetzt für C, hier ist das Problem höherer Ordnung. Ich habe nicht die syntaktische Fähigkeit in C, Dinge so zu abstrahieren, dass ich beim Kompilieren Optimierungen durchführen oder Invarianten überprüfen kann. Daher kann ich Dinge nicht richtig kapseln, sodass der Benutzer nicht wissen muss, wie sie funktionieren, um sie zu verwenden, und der größte Teil meiner Fehlererkennung erfolgt zur Laufzeit (was nicht nur zu spät ist, sondern auch zusätzliche Kosten verursacht). Grundsätzlich ist die einzige Möglichkeit, in C generisch zu sein, Daten zu verwenden. Ich übergebe einen Format-String an printf oder scanf, der beispielsweise zur Laufzeit ausgewertet wird. Für den Compiler ist es dann ziemlich schwierig zu beweisen, dass ich einige der Optionen nicht verwende, die theoretisch möglich sind, wenn die richtigen Daten übergeben werden, was potenzielle Generierung von totem Code und Verlust von Optimierungspotential bedeutet.

Ich weiß, dass ich hier vielleicht einen Scheiß auslöse, aber meine Erfahrung mit 32-Bit-Mikrocontrollern ist, dass in einem Apfel-zu-Apfel-Vergleich von C und C ++, die beide von Experten geschrieben wurden (wie in C ++, das möglicherweise stark von Templaten betroffen ist), C ++ die effizientere Sprache ist, sobald Alles muss generisch sein (wie in jeder Bibliothek) und in nicht generischen Fällen sind sie im Wesentlichen gleichwertig. Es ist für Anfänger auch einfacher, das Fachwissen eines Experten für die Implementierung von Bibliotheken in C ++ zu nutzen.

Gleichzeitig gibt es tatsächlich wirklich wenige Funktionen, an die ich keine falschen Daten übergeben kann, sobald die Eingabe kein int ist, somethingfür die ich aber zufällig ein int als Darstellungsmethode verwende, besteht die Möglichkeit, dass ich sie bekomme falsch (übergebe einen ungültigen Wert oder ein 'otherThing' anstatt eines 'something'). In C kann ich nur zur Laufzeit prüfen, ob der Benutzer etwas falsch gemacht hat. In C ++ habe ich die Möglichkeit, einige Überprüfungen durchzuführen, nicht alle Überprüfungen, sondern einige Überprüfungen zur Kompilierungszeit, die frei sind.

Am Ende des Tages ist ein C-Team oft so mächtig wie sein schwächster Programmierer, und der Vorteil des resultierenden Codes besteht entweder in einem 1er-Multiplayer oder in einer Leistungsstrafe. Was ich damit meine, ist, dass es entweder eine hohe Leistung für einen und nur einen einzigen Auftrag in einer einzigartigen Umgebung mit einzigartigen Entwurfsentscheidungen bietet oder generisch genug ist, um in mehreren Umgebungen verwendet zu werden (anderer Mikrocontroller, andere Speichermanagementstrategie, andere Latenz vs. Durchsatzkompromisse usw. usw.), hat jedoch inhärente Leistungskosten.

In C ++ können Dinge von Experten gekapselt und in vielen Umgebungen verwendet werden, in denen sich die Generierung von Kompilierungs-Zeitcode an die jeweilige Aufgabe anpasst und die statische Überprüfung Benutzer davon abhält, dumme Dinge zu Nullkosten zu erledigen. Hier haben wir einen weitaus geringeren Kompromiss zwischen allgemeinem und schnellem Sprachgebrauch. Letztendlich ist die Sprache unter Kosten-Nutzen-Gesichtspunkten performanter, sicherer und produktiver.

Es ist eine berechtigte Kritik, dass es immer noch einen großen Mangel an guten C ++ - Bibliotheken für Embedded gibt. Dies kann zu pragmatischen Entscheidungen führen, hauptsächlich C auf einem C ++ - Compiler zu verwenden. Die Entscheidung, in einem Projekt nur C zu verwenden, ist im Wesentlichen entweder ideologisch motiviert, aus Gründen der Legacy-Unterstützung oder dem Eingeständnis, dass das Team nicht diszipliniert genug ist, um von einer Reihe sehr ausgewählter dummer Dinge Abstand zu nehmen, die man in C ++, aber nicht in C tun kann und gleichzeitig diszipliniert genug, um keine der weitaus größeren dummen Dinge zu tun, gegen die man sich in C nicht schützen kann, aber in C ++ könnte.


Netter Zusatz zu meiner Antwort :) Wer wäre dieser mysteriöse C ++ Liebhaber? In seinem Profil heißt es: "Offensichtlich zieht es dieser Benutzer vor, ein Geheimnis um sie zu hegen." (schlechtes Englisch, Übrigens) ABER AHA der Ort ist "Bochum, Deutschland" ..... Wir sehen uns auf der Konferenz!
Wouter van Ooijen

Ah yeah hat mein Profil aktualisiert;) Schön zu wissen, dass du zu emBO ++ kommst, es wird eine gute Menge sein
odinthenerd

10

Mein Hintergrund: gerade nach der Schulausbildung bei alten Bell Labs-Programmierern; Ich arbeite seit 3 ​​Jahren, 2 an einem Undergrad-Forschungsprojekt. Datenerfassung / Prozesskontrolle in VB.NET. Verbrachte 1,5 Jahre mit der Arbeit an einer Unternehmensdatenbankanwendung in VB6. Derzeit wird an einem Projekt für einen Embedded- PC mit 2 GB Speicher, 512 MB RAM und 500 MHz x 86-CPU gearbeitet. Mehrere Apps, die gleichzeitig in C ++ mit einem dazwischen liegenden IPC-Mechanismus ausgeführt werden. Ja ich bin jung

Meine Meinung: Ich denke, C ++ kann in der oben beschriebenen Umgebung effektiv arbeiten . Zugegebenermaßen ist eine harte Echtzeitleistung keine Voraussetzung für die App, auf der ich arbeite, und in einigen eingebetteten Anwendungen kann dies 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 für C gültig ist, für C ++ gilt, ist C ++ eine ganz andere Sprache und man muss lernen, wie man in C ++ programmiert und nicht in C, um es in jeder Situation effektiv zu nutzen . In C ++ müssen Sie objektorientiert programmieren, nicht prozedural und nicht hybrid (große Klassen mit vielen Funktionen). Im Allgemeinen sollten Sie sich darauf konzentrieren, kleine Klassen mit wenigen Funktionen zu erstellen und alle kleinen Klassen zusammen zu einer größeren Lösung zusammenzufassen. Einer meiner Kollegen erklärte mir, dass ich früher prozedural in Objekten programmiert habe, was ein großes Durcheinander ist und schwer zu pflegen ist. Als ich anfing, objektorientiertere Techniken anzuwenden, stellte ich fest, dass die Wartbarkeit / Lesbarkeit meines Codes verbessert wurde.

  • C ++ bietet zusätzliche Funktionen in Form einer objektorientierten Entwicklung, mit denen sich Code vereinfachen und leichter lesen und pflegen lässt . Ehrlich gesagt glaube ich nicht, dass eine Verbesserung der Leistung / Raumeffizienz beim Ausführen von 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 der dynamischen Speicherzuweisung zu tun. C hat das gleiche Problem auch. Sie können eine objektorientierte Anwendung schreiben, ohne dynamischen Speicher zu verwenden. Einer der Vorteile der Verwendung von Objekten besteht jedoch darin, dass Sie diese Dinge auf einfache Weise dynamisch zuordnen können. Genau wie in C müssen Sie vorsichtig sein, wie die Daten verwaltet werden, um Speicherverluste zu reduzieren. Die RAII-Technik vereinfacht dies jedoch in C ++ (dynamische Speicherzerstörung wird automatisch durch Kapselung in Objekte durchgeführt). In einigen Anwendungen, in denen jeder Speicherort zählt, ist dies möglicherweise zu wild und zu wollig, um verwaltet zu werden.

BEARBEITEN:

  • WRT die Frage "Arduino C ++" : Ich würde argumentieren, dass C ++ ohne dynamische Speicherverwaltung immer noch nützlich sein kann. Sie können Ihren Code in Objekten organisieren und diese Objekte dann an verschiedenen Stellen in Ihrer Anwendung platzieren, Rückrufschnittstellen einrichten usw. Jetzt, da ich in C ++ entwickelt habe, kann ich viele Möglichkeiten sehen, wie eine Anwendung mit allen Daten auf dem Computer zugeordnet wird Stapel kann immer noch mit Objekten nützlich sein. Ich gebe es jedoch zu - ich habe noch nie eine solche eingebettete App für den Arduino geschrieben, daher habe ich keinen Beweis für meine Behauptung. Ich habe einige Möglichkeiten, in einem bevorstehenden Projekt Arduino-Entwicklung zu betreiben - hoffentlich kann ich meinen Anspruch dort testen.

2
Ich möchte zu Ihrem zweiten Punkt sagen, dass es hilft, ein komplexes Problem in viele kleine Teile aufzuteilen, und dass dieses Feature ignoriert werden sollte. Dies ist der genaue Grund, warum ich so Pro-C ++ bin. Eine sehr große Anzahl von Untersuchungen zur Programmierung zeigt, dass ein lineares Anwachsen der Programmgröße zu einem exponentiellen Anwachsen der Entwicklungszeit führt. Dies ist umgekehrt, wenn Sie ein Programm richtig aufteilen können, können Sie einen exponentiellen Abfall der Entwicklungszeit angeben. Dies ist bei weitem das Wichtigste.
Kortuk

Auch zu Ihrem zweiten Punkt: Die einfache Verwendung einer OOP-Entwurfsmethodik führt nicht zu mehr Code-Kompartimenten. Wenn man ein gutes Basisdesign hat, bleibt es dem Entwickler überlassen, wie man dieses Design ausdrückt. OOP definiert nicht, dass Sie Ihren Code richtig trennen, es bietet eine weitere Option und darüber hinaus das Erscheinungsbild, das Sie dies getan haben, aber es erzwingt sicherlich kein gutes Design, das dem Entwickler überlassen bleibt.
Mark

Das ist immer wahr Ich habe noch nie von einer Sprache gehört, die gutes Design durchsetzt. Ich denke, wir implizieren meistens, dass dies die Aufgabe der Entwickler ist und dass C ++ es einfach macht, es auf organisierte Weise zu verwenden und zu implementieren.
Kortuk

@ Mark - ich stimme zu. Es war ein Lernprozess für mich.
J. Polfer

7

Ja, das Problem mit C ++ ist der größere Platzbedarf des Codes.

In einigen Systemen zählen Sie Bytes, und in diesem Fall müssen Sie die Betriebskosten in Kauf nehmen, die so hoch sind, dass die Entwicklungskosten für C nahe an den Grenzen Ihrer Systeme liegen.

Aber selbst in C müssen Sie für ein gut gestaltetes System alles gekapselt lassen. Gut konzipierte Systeme sind schwierig, und C ++ bietet Programmierern einen Platz für eine sehr strukturierte und kontrollierte Entwicklungsmethode. Das Erlernen von OOP ist mit Kosten verbunden, und wenn Sie darauf wechseln möchten, akzeptieren Sie dies sehr. In vielen Fällen würde das Management lieber mit C fortfahren und die Kosten nicht bezahlen, da es schwierig ist, die Ergebnisse eines solchen Wechsels zu messen erhöht die Produktivität. Einen Artikel des Embedded-Systems-Gurus Jack Ganssle finden Sie hier .

Dynamische Speicherverwaltung ist der Teufel. Nicht wirklich, der Teufel ist die automatische Weiterleitung. Dynamische Speicherverwaltung funktioniert auf einem PC hervorragend, aber Sie können davon ausgehen, dass Sie mindestens alle paar Wochen einen PC neu starten. Sie werden feststellen, dass ein eingebettetes System, das 5 Jahre lang weiterarbeitet, die dynamische Speicherverwaltung stark beeinträchtigen kann und tatsächlich ausfällt. Ganssle beschreibt Dinge wie Stapel und Haufen in seinem Artikel.

Es gibt einige Dinge in C ++, die eher zu Problemen führen und viele Ressourcen verbrauchen. Das Entfernen der dynamischen Speicherverwaltung und der Vorlagen sind große Schritte, um den Footprint von C ++ näher an den Footprint von C heranzuführen. Dies ist immer noch C ++, Sie benötigen kein dynamisches Format 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 Veröffentlichung entferne, aber bis dahin verwende. Beim Feldtest können Ausnahmen Meldungen generieren, um mich über das Auftreten einer Ausnahme zu informieren.


1
Früher war ich mir einig, dass der Code-Footprint ein Problem ist, aber in letzter Zeit scheint die Flash-Größe nur einen geringen Einfluss auf den Preis eines Mikrocontrollers zu haben, viel weniger als die RAM-Größe oder die Anzahl der IO-Pins.
Wouter van Ooijen

Das Argument zum dynamischen Speicher ist IMO wichtiger. Ich habe industrielle Systeme gesehen, die wochenlang ohne Unterbrechung laufen konnten, aber die Diagnoseschicht (in C ++ geschrieben) würde die Zeit für einen Neustart auf etwa 12 Stunden begrenzen.
Dmitry Grigoryev

6

Ich fand diesen Anti-C ++ - Rant von Linus Torvalds interessant.

Eine der absolut schlimmsten Eigenschaften von C ++ ist, dass viele Dinge so kontextabhängig sind - was nur bedeutet, dass eine lokale Ansicht beim Betrachten des Codes nur selten genug Kontext bietet, um zu wissen, was vor sich geht.

Er spricht nicht von der Welt der eingebetteten Systeme, sondern von der Entwicklung des Linux-Kernels. 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 einigen Monaten aktualisieren muss.

(Andererseits arbeite ich derzeit an einem eingebetteten Gerät mit Python (nicht C ++, aber mit demselben OOP-Paradigma), das genau dieses Problem hat. Zu meiner Verteidigung ist es ein eingebettetes System, das leistungsfähig genug ist, um als PC bezeichnet zu werden.) vor 10 Jahren.)


5
Wir mögen uns unterscheiden, aber ich stelle fest, dass ich beim Öffnen eines Projekts nicht sofort sagen kann, was gerade passiert. Wenn ich jedoch etwas über dessen Funktionsweise weiß und etwas in C und etwas in C ++ gut codiertes habe, scheint das C ++ immer mehr zu sein klar. Sie müssen noch eine Kapselung für eine gute Entwicklung in C implementieren, was mit C ++ sehr einfach zu bewerkstelligen ist. Die ordnungsgemäße Verwendung von Klassen kann deutlich machen, wo sich Ihre Schnittstellen befinden, und sie können vollständig über ein Objekt verwaltet werden.
Kortuk

Völlig einig über Kapselung und Klassen. Überlastung und Vererbung von Operatoren, nicht so sehr.
Pingswept

1
Haha, ja, das Überladen von Operatoren kann verwendet werden, um die Funktion von Code zu verschleiern. Wenn jemand den Bediener überlastet, muss dies aus eindeutigen Gründen geschehen oder überhaupt nicht. Die Vererbung sollte nur in bestimmten Fällen verwendet werden, in denen Sie tatsächlich etwas tun, das dem übergeordneten Element mit einigen Ergänzungen gleicht. Ich denke, ich würde nicht jede Funktion in OOP verwenden. Ich habe beide verwendet, aber in einem eingebetteten System kann ich mir keinen Fall vorstellen, in dem ich würde. Genau wie ich denke, sollte ein Compiler mit einer Beschränkung von 80 Zeichen für Variablennamen sofort ausrangiert werden.
Kortuk

2
Ich warf mich nur ein wenig in den Mund, als ich daran dachte, eine MCU in Python zu programmieren ...
vicatcu

Sie sind nicht der einzige, aber wenn es gut funktioniert und effizient ist, kann ich vergeben.
Kortuk

6

Ich denke, andere Antworten haben die Vor- und Nachteile sowie die Entscheidungsfaktoren ziemlich gut dargelegt, daher möchte ich nur ein paar Kommentare zusammenfassen und hinzufügen.

Für kleine Mikrocontroller (8-Bit) auf keinen Fall. Sie bitten nur, sich selbst zu verletzen, es gibt keinen Gewinn und Sie geben zu viele Ressourcen auf.

Für High-End-Mikrocontroller (z. B. 32-Bit, 10 oder 100 MB für RAM und Speicher) mit einem anständigen Betriebssystem ist dies vollkommen in Ordnung und kann sogar empfohlen werden.

Die Frage ist also: Wo ist die Grenze?

Ich weiß es nicht genau, aber ich habe einmal ein 16-Bit-uC-System mit 1 MB RAM und 1 MB Speicher in C ++ entwickelt, 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 fit machen, sicherstellen, dass Dinge wie Ausnahmen keine Lecks produzieren (die Unterstützung von OS + RTL war ziemlich fehlerhaft und unzuverlässig). Darüber hinaus führt eine OO-App in der Regel viele kleine Zuweisungen durch, und der Mehraufwand für diese war ein weiterer Albtraum.

Aufgrund 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 RAM und Speicher wählen werde. Dies ist eine willkürliche Grenze und hängt wahrscheinlich von der Art der Anwendung, den Codierungsstilen und Redewendungen usw. ab. Angesichts der Einschränkungen würde ich einen ähnlichen Ansatz empfehlen.


2
Ich muss hier nicht zustimmen, das ist kein plötzlicher Punkt, an dem C ++ aufgrund von Systemressourcen akzeptabel wird. Eine gute Entwurfspraxis kann den Footprint von C ++ beibehalten, wo der Footprint von C ist. Dies führt zu Code mit OOP-Entwürfen, die denselben Platz beanspruchen. Schlecht geschriebenes C kann genauso schlecht sein.
Kortuk

1
Nun, es hängt davon ab, wie groß Ihre Anwendung ist und wie oft Sie bestimmte Funktionen verwenden, die mehr Speicherplatz erfordern (wie Vorlagen und Ausnahmen). Aber persönlich würde ich lieber C verwenden, als mich auf ein zurückhaltendes C ++ beschränken zu müssen. Aber selbst dann haben Sie den Overhead einer größeren RTL, Virtual Method Thunks, Konstruktor / Destruktor-Kettenaufruf ... Diese Effekte können durch sorgfältiges Codieren gemindert werden, aber dann verlieren Sie den Hauptgrund für die Verwendung von C ++, Abstraktion und hohe Perspektive.
Fceconel

4

Es gibt einige Funktionen von C ++, die in eingebetteten Systemen nützlich sind. Es gibt andere, wie zum Beispiel Ausnahmen, die teuer sein können und deren Kosten nicht immer offensichtlich sind.

Wenn ich meine Druthers hätte, würde es eine populäre Sprache geben, die das Beste aus beiden Welten kombiniert und einige Merkmale enthält, die in beiden Sprachen fehlen. Einige Anbieter bieten einige dieser Funktionen an, es gibt jedoch keine Standards. Ein paar Dinge, die ich gerne sehen würde:

  1. Die Ausnahmebehandlung ähnelt etwas Java, wo Funktionen, die Ausnahmen auslösen oder auslassen können, als solche deklariert werden müssen. Während eine Anforderung für solche Deklarationen aus Programmiersicht etwas ärgerlich sein kann, würde sie die Klarheit des Codes in Fällen verbessern, in denen eine Funktion eine beliebige Ganzzahl zurückgeben kann, wenn sie erfolgreich ist, aber auch fehlschlägt. Viele Plattformen könnten dies kostengünstig im Code handhaben, indem sie z. B. den Rückgabewert in einem Register und eine Erfolgs- / Fehleranzeige im Übertragsflag haben.
  2. Überladen nur von statischen und Inline-Funktionen; Ich verstehe, dass die Normierungsgremien für C eine Überlastung der Funktionen vermieden haben, um die Notwendigkeit einer Namensänderung zu vermeiden. Das Zulassen von Überladungen nur für statische und Inline-Funktionen würde dieses Problem vermeiden und 99,9% des Nutzens des Überladens externer Funktionen bieten (da .h-Dateien Inline-Überladungen in Bezug auf unterschiedlich benannte externe Funktionen definieren könnten).
  3. Überladungen für beliebige oder bestimmte, zur Kompilierungszeit auflösbare konstante Parameterwerte. Einige Funktionen können sehr effizient inline sein, wenn sie mit einem konstanten Wert übergeben werden, aber sehr schlecht inline, wenn sie eine Variable übergeben. Ein anderer Zeitcode, der eine Optimierung sein kann, wenn ein Wert konstant ist, kann eine Pessimisierung sein, wenn dies nicht der Fall ist. Zum Beispiel:
    inline void copy_uint32s (uint32_t * dest, const uint32_t * src, __is_const int n)
    {
      if (n <= 0) return;
      sonst wenn (n == 1) {dest [0] = src [0];}
      sonst wenn (n == 2) {dest [0] = src [0]; dest [1] = src [1];}
      sonst wenn (n == 3) {dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2];}
      sonst wenn (n == 4) {dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2]; dest [3] = src [3];}
      sonst memcpy ((void *) dest, (const void *) src, n * sizeof (* src));
    }
    
    Wenn 'n' zur Kompilierungszeit ausgewertet werden kann, ist der obige Code effizienter als ein Aufruf von memcpy. Wenn 'n' zur Kompilierungszeit jedoch nicht ausgewertet werden kann, ist der generierte Code viel größer und langsamer als Code, der einfach ist memcpy genannt.

Ich weiß, der Vater von C ++ ist nicht besonders an einer Embedded-Only-Version von C ++ interessiert, aber ich würde denken, dass es einige erhebliche Verbesserungen gegenüber der Verwendung von C bieten könnte.

Weiß jemand, ob so etwas für irgendeine Art von Norm in Betracht gezogen wird?



@Joby Taffey: Ich glaube, ich habe meinen Beitrag bearbeitet, um nicht zu erwähnen, dass der Ersteller von C ++ keine Lust auf eine eingebettete Teilmenge hatte. Ich bin mir bewusst, dass es Anstrengungen gab, aber nach meinem Verständnis waren sie noch nicht so weit gekommen. Ich denke, es gibt definitiv eine Verwendung für eine standardisierte Sprache, die für 8-Bit-Prozessoren geeignet ist, und Funktionen wie die oben beschriebenen scheinen auf jeder Plattform nützlich zu sein. Haben Sie schon von Sprachen gehört, die Dinge wie die Nummer 3 anbieten? Es scheint sehr nützlich zu sein, aber ich habe noch nie eine Sprache gesehen, die es anbietet.
Supercat

"Der Vater von C ++" hat keine Erfahrung mit der Programmierung eingebetteter Systeme. Warum sollte sich jemand für seine Meinung interessieren?
Lundin

@Lundin: Die Tatsache, dass sich einige einflussreiche Personen anscheinend für seine Meinung zu verschiedenen Themen interessieren, scheint für sich genommen ein Grund zu sein, dies für andere zu tun. Ich bin der Meinung, dass die zunehmende Leistung von Vorlagen seit dem Schreiben des Vorstehenden neue Möglichkeiten für Überladungen auf der Grundlage der Konstanten eröffnet hat, die zur Kompilierungszeit aufgelöst werden können, obwohl dies weitaus weniger sauber ist, als wenn eine solche Funktion als Kompilierungsprogramm unterstützt würde.
Zeitfunktion

... aber dafür müsste der Compiler einiges an Aufwand aufwenden, um mögliche Substitutionen zusammenzustellen, die dann verworfen würden. Sauberer sagen zu können, "Wenn dies eine Konstante ist, tue dies, andernfalls tue dies" ohne "Fehlstarts", scheint ein sauberer Ansatz zu sein.
Supercat

3

C ++ ist mehr als eine Programmiersprache:

a) Es ist eine "bessere" C b) Es ist eine objektorientierte Sprache c) Es ist eine Sprache, mit der wir generische Programme schreiben können

Obwohl alle diese Funktionen separat verwendet werden können, werden die besten Ergebnisse erzielt, wenn die drei Funktionen gleichzeitig verwendet werden. Wenn Sie jedoch nur eine davon auswählen, erhöht sich die Qualität der eingebetteten Software.

a) Es ist ein "besseres" C

C ++ ist eine stark typisierte Sprache. stärker als C. Ihre Programme werden von dieser Funktion profitieren.

Einige Leute haben Angst vor Zeigern. C ++ enthält die Referenzen. Überladene Funktionen.

Und es lohnt sich zu erwähnen: Keine dieser Funktionen tritt in größeren oder langsameren Programmen auf.

b) Es ist eine objektorientierte Sprache

Jemand sagte in diesem Beitrag, 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 Steuer als der von C ++. Das Problem, das ich mit diesem Argument sehe, ist, dass einige Programmierer nicht daran gewöhnt sind, in Objekten zu denken. Auf diese Weise sehen sie die Vorteile von OOP nicht.

Wann immer Sie bereit sind, das Peripheriegerät eines Mikrocontrollers zu verwenden, ist es wahrscheinlich, dass das Peripheriegerät in Form des Gerätetreibers für uns (von Ihnen selbst oder von Dritten) abstrahiert wurde. Wie ich bereits sagte, verwendet dieser Treiber die C-Sintax, wie das folgende 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);

Sehen Sie die Abstraktion? Wenn Sie also C ++ für den gleichen Zweck verwenden, wird die Abstraktion durch den Abstraktions- und Kapselungsmechanismus von C ++ auf die nächste Ebene gebracht, und zwar zu Nullkosten!

c) Es ist eine Sprache, mit der wir generische Programme schreiben können

Generische Programme werden über Vorlagen erstellt, und Vorlagen sind für unsere Programme ebenfalls kostenlos.

Außerdem wird mit Vorlagen ein statischer Polymorphismus erzielt.

Virtuelle Methoden, RTTI und Ausnahmen.

Bei der Verwendung virtueller Methoden gibt es einen Kompromiss: Bessere Software vs. Leistungseinbußen. Beachten Sie jedoch, dass die dynamische Bindung wahrscheinlich mithilfe einer virtuellen Tabelle (einem Array von Funktionszeigern) implementiert wird. Ich habe dasselbe in C oft gemacht (auch regelmäßig), so dass ich die Nachteile der Verwendung virtueller Methoden nicht sehe. Darüber hinaus sind virtuelle Methoden in C ++ eleganter.

Abschließend ein Hinweis zu RTTI und Ausnahmen: VERWENDEN SIE SIE NICHT in eingebetteten Systemen. Vermeiden Sie sie um jeden Preis!


2

Mein Hintergrund, eingebettet (mcu, pc, unix, andere), Echtzeit. Sicherheitskritisch. Ich habe einen früheren Arbeitgeber bei STL vorgestellt. Das mache ich nicht mehr

Einige Flammeninhalte

Ist C ++ für eingebettete Systeme geeignet?

Meh. C ++ ist ein Schmerz zu schreiben und ein Schmerz zu pflegen. C + ist in Ordnung (benutze einige Funktionen nicht)

C ++ in Mikrocontrollern? RTOSes? Toaster? Embedded-PCs?

Wieder sage ich Meh. C + ist nicht schlecht, aber ADA ist weniger schmerzhaft (und das sagt wirklich etwas aus). Wenn du Glück hast wie ich, kannst du Embedded Java machen. Ein überprüfter Array-Zugriff und keine Zeigerarithmetik ergeben einen sehr zuverlässigen Code. Garbage Collectors in eingebettetem Java haben nicht die höchste Priorität, und die Wiederverwendung von Speicher und Objekten ist begrenzt, sodass gut gestalteter Code ohne GC für immer ausgeführt werden kann.

Ist OOP für Mikrocontroller nützlich?

Sicher ist. Der UART ist ein Objekt ..... Der DMAC ist ein Objekt ...

Objektzustandsautomaten 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, sodass Bjarne Stroustrup nicht mehr darüber belacht wurde, dass er bei AT & T langsame Simula-Simulationen hatte. C ++ ist nicht Ihre CPU.

Holen Sie sich eine MCU, die Java-Bytecodes ausführt. Programm in Java. Lache über die C Jungs.

Sollte Arduinos C ++ (ohne dynamische Speicherverwaltung, Vorlagen, Ausnahmen) als "echtes C ++" betrachtet werden?

Nee. Genau wie alle bastardisierten C-Compiler für MCUs.

Forth, Embedded Java oder Embedded ADA sind standardisiert (ish); Alles andere ist Trauer.


2
Ist es so einfach, Mikrocontroller zu finden, die Java unterstützen? Ich denke, dies würde die Auswahl erheblich einschränken. Und wie stehen Sie zu Performance-Einbußen (da Sie in den USA normalerweise keine JIT haben)? Was ist mit den Auswirkungen der Unvorhersehbarkeit von GC in Echtzeitsystemen?
Fceconel

2
Welche MCUs gibt es, die Embedded Java unterstützen?
J. Polfer

www.ajile.com für den Anfang.
Tim Williscroft

+1 für Ada. In Embedded ist eine Menge los, einschließlich Arduinos.
Brian Drummond

Portable Java VM für in c geschriebene Mikros ist Open Source. dmitry.co/index.php?p=./04.Thoughts/…
Tim Williscroft

-2

Eingebettete Systeme sind so konzipiert, dass sie eine bestimmte Aufgabe erfüllen und nicht als Universalcomputer für mehrere Aufgaben dienen. Ein eingebettetes System ist eine Kombination aus Computerhardware und -software. C ist die Mutter aller modernen Sprachen. Es handelt sich um eine Sprache mit niedrigem Sprachniveau und voller Leistung, die sich mit allen Arten von Hardware befasst. 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 bei einer erfolgreichen Softwareentwicklung häufig die beste Sprache für ein bestimmtes Projekt ausgewählt wird, ist es überraschend, dass sich die C / C ++ - Sprache sowohl für 8-Bit- als auch für 64-Bit-Prozessoren als geeignet erwiesen hat ; in Systemen mit Byte, Kilobyte und Megabyte Arbeitsspeicher. C hat den Vorteil der Prozessorunabhängigkeit, Dadurch können sich Programmierer auf Algorithmen und Anwendungen konzentrieren und nicht auf die Details einer bestimmten Prozessorarchitektur. Viele dieser Vorteile gelten jedoch auch für andere Hochsprachen. Aber C / C ++ war erfolgreich, wo so viele andere Sprachen größtenteils gescheitert sind?


6
Ich bin mir wirklich nicht sicher, was dies zur Diskussion beiträgt.
Dave Tweed

-3

<rant>

Ich denke, C ++ ist in erster Linie eine beschissene Sprache. Wenn Sie OOP verwenden möchten, schreiben Sie Java-Programme. C ++ tut nichts, um OOP-Paradigmen durchzusetzen, da Sie den direkten Speicherzugriff voll und ganz nutzen können.

Wenn Sie eine MCU haben, handelt es sich höchstwahrscheinlich um weniger als 100 KB Flash-Speicher. Sie möchten in einer Sprache programmieren, deren Speicherabstraktion folgendermaßen lautet: Wenn ich eine Variable oder ein Array deklariere, erhält sie Speicher, Punkt; malloc (alias "neues" Schlüsselwort in C ++) sollte mehr oder weniger für die Verwendung in eingebetteter Software gesperrt sein, außer vielleicht in seltenen Fällen, wenn ein Aufruf während des Programmstarts erfolgt.

Zum Teufel, es gibt (häufig) Zeiten in der eingebetteten Programmierung, in denen C nicht niedrig genug ist, und Sie müssen Dinge wie die Zuweisung von Variablen zu Registern und das Schreiben einer Inline-Assembly durchführen, um Ihre Interrupt-Service-Routinen (ISRs) zu straffen. Keywords wie "volatile" werden verdammt wichtig zu verstehen. Sie verbringen viel Zeit damit, den Speicher auf der Bit- Ebene zu manipulieren , nicht auf der Objektebene .

Warum sollten Sie sich vormachen, die Dinge seien einfacher als sie tatsächlich sind?

</ rant>


Mein Problem hier ist einfach, warum ich die Komplexität des Treibers wissen möchte, der zur Steuerung von USART1 geschrieben wurde, wenn er für die Handhabung der Schnittstelle vollständig entwickelt wurde.
Kortuk

1
Ich habe Sie nicht abgewählt, aber ich möchte darauf hinweisen, dass C ++ OOP nicht erzwingen muss, sondern nur die Tools dafür bereitstellt. Die Durchsetzung guter Codierungsstandards ist Aufgabe des Entwicklers. Es kann helfen, wenn die Sprache es einfacher macht, aber die Sprache wird es niemals alleine tun. C kann in einigen Fällen unlesbar sein.
Kortuk

1
Alle Sprachen sind gut für etwas. C ++ ist schnell. Wenn OOP gut gemacht ist, ist es für mehrere Entwickler viel einfacher, parallel zu arbeiten und für das Unbekannte zu programmieren. Ich denke, das ist der Grund, warum es so viel Traktion in der Spieleentwicklung hat.
Toby Jaffey

1
Ja, ich stimme zu. Der Grund, warum ich es für die eingebettete Welt sehe, liegt in der Fülle von Merkmalen und Funktionen, die viele der bereits vorhandenen Systeme ergänzen und neue Systeme entwickeln. Das Projekt wird immer größer. Entweder wir brauchen länger, um sie zu entwickeln, oder wir beginnen, das, was die CS-Welt bereits auf PCs getan hat, anzuwenden und zu verzerren.
Kortuk

5
Noch eine Person, die C ++ nicht richtig versteht. Es wundert mich immer, wie viele es gibt.
Rocketmagnet
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.