Frage
Ich habe zwei Compiler auf meiner Hardware C ++ und C89
Ich denke darüber nach, C ++ mit Klassen, aber ohne Polymorphismus zu verwenden (um vtables zu vermeiden). Die Hauptgründe, warum ich C ++ verwenden möchte, sind:
- Ich bevorzuge die Verwendung von Inline-Funktionen anstelle von Makrodefinitionen.
- Ich möchte Namespaces verwenden, da Präfixe den Code überladen.
- Ich sehe C ++ ein bisschen sicherer, hauptsächlich wegen der Vorlagen und des ausführlichen Castings.
- Ich mag überladene Funktionen und Konstruktoren (die für das automatische Casting verwendet werden) sehr.
Sehen Sie einen Grund, bei der Entwicklung für sehr begrenzte Hardware (4 KB RAM) bei C89 zu bleiben?
Fazit
Vielen Dank für Ihre Antworten, sie waren wirklich hilfreich!
Ich habe das Thema durchdacht und werde mich hauptsächlich an C halten, weil:
- Es ist einfacher, den tatsächlichen Code in C vorherzusagen, und dies ist sehr wichtig, wenn Sie nur 4 KB RAM haben.
- Mein Team besteht hauptsächlich aus C-Entwicklern, daher werden erweiterte C ++ - Funktionen nicht häufig verwendet.
- Ich habe einen Weg gefunden, Funktionen in meinem C-Compiler (C89) zu integrieren.
Es ist schwer, eine Antwort zu akzeptieren, da Sie so viele gute Antworten gegeben haben. Leider kann ich kein Wiki erstellen und akzeptieren, daher werde ich eine Antwort auswählen, die mich am meisten zum Nachdenken gebracht hat.
Antworten:
Zwei Gründe für die Verwendung von C über C ++:
In der ursprünglichen Frage und in einer Reihe von Kommentaren werden auch die 4 KB RAM erwähnt . Bei einem typischen eingebetteten Prozessor hängt die RAM-Größe (meistens) nicht von der Codegröße ab, da der Code gespeichert wird und von Flash ausgeführt wird.
Sicherlich ist die Menge an Code-Speicherplatz zu berücksichtigen, aber da neue, leistungsfähigere Prozessoren auf dem Markt erscheinen, ist dies weniger ein Problem als früher für alle außer den kostensensitivsten Projekten.
Zur Verwendung einer Teilmenge von C ++ zur Verwendung mit eingebetteten Systemen: Es gibt jetzt einen MISRA C ++ - Standard, der einen Blick wert sein kann.
EDIT: Siehe auch diese Frage , die zu einer Debatte über C vs C ++ für eingebettete Systeme führte.
quelle
Für ein sehr ressourcenbeschränktes Ziel wie 4 KB RAM würde ich das Wasser mit einigen Beispielen testen, bevor ich viel Aufwand unternehme, der nicht einfach in eine reine ANSI C-Implementierung zurückportiert werden kann.
Die Arbeitsgruppe Embedded C ++ schlug eine Standarduntermenge der Sprache und eine dazugehörige Standarduntermenge der Standardbibliothek vor. Ich habe diese Bemühungen leider aus den Augen verloren, als das C User's Journal starb. Es sieht so aus, als gäbe es einen Artikel bei Wikipedia und das Komitee existiert noch.
In einer eingebetteten Umgebung müssen Sie bei der Speicherzuweisung wirklich vorsichtig sein. Um diese Sorgfalt durchzusetzen, müssen Sie möglicherweise das Globale
operator new()
und seine Freunde für etwas definieren, das nicht einmal verknüpft werden kann, damit Sie wissen, dass es nicht verwendet wird. Die Platzierungnew
hingegen ist wahrscheinlich Ihr Freund, wenn sie mit Bedacht zusammen mit einem stabilen, threadsicheren und latenzgarantierten Zuweisungsschema verwendet wird.Inline-Funktionen verursachen keine großen Probleme, es sei denn, sie sind groß genug, um eigentlich echte Funktionen zu sein. Natürlich hatten die Makros, die sie ersetzten, das gleiche Problem.
Auch Vorlagen verursachen möglicherweise kein Problem, es sei denn, ihre Instanziierung wird amok ausgeführt. Überprüfen Sie für jede Vorlage, die Sie verwenden, Ihren generierten Code (die Link-Map enthält möglicherweise genügend Hinweise), um sicherzustellen, dass nur die von Ihnen beabsichtigten Instanziierungen ausgeführt wurden.
Ein weiteres Problem, das auftreten kann, ist die Kompatibilität mit Ihrem Debugger. Es ist nicht ungewöhnlich, dass ein ansonsten verwendbarer Hardware-Debugger die Interaktion mit dem ursprünglichen Quellcode nur sehr eingeschränkt unterstützt. Wenn Sie in Assembly effektiv debuggen müssen, kann die interessante Namensverknüpfung von C ++ die Aufgabe zusätzlich verwirren.
RTTI, dynamische Casts, Mehrfachvererbung, starker Polymorphismus und Ausnahmen verursachen für ihre Verwendung einige Laufzeitkosten. Einige dieser Funktionen kosten das gesamte Programm, wenn sie verwendet werden, andere erhöhen lediglich das Gewicht der Klassen, die sie benötigen. Kennen Sie den Unterschied und wählen Sie erweiterte Funktionen mit Bedacht aus, wobei Sie mindestens eine flüchtige Kosten-Nutzen-Analyse kennen.
In einer kleinen eingebetteten Umgebung stellen Sie entweder eine direkte Verbindung zu einem Echtzeitkern her oder laufen direkt auf der Hardware. In beiden Fällen müssen Sie sicherstellen, dass Ihr Laufzeit-Startcode die C ++ - spezifischen Startaufgaben korrekt behandelt. Dies ist möglicherweise so einfach wie die Verwendung der richtigen Linker-Optionen. Da es jedoch üblich ist, die direkte Kontrolle über die Quelle zum Einschalt-Reset-Einstiegspunkt zu haben, müssen Sie dies möglicherweise überprüfen, um sicherzustellen, dass alles funktioniert. Auf einer ColdFire-Plattform, an der ich gearbeitet habe, wurden die Entwicklertools beispielsweise mit einem CRT0.S-Modul geliefert, in dem die C ++ - Initialisierer vorhanden waren, das jedoch auskommentiert wurde. Wenn ich es direkt aus der Box verwendet hätte, wäre ich von globalen Objekten verwirrt worden, deren Konstruktoren überhaupt nicht ausgeführt worden waren.
In einer eingebetteten Umgebung ist es häufig erforderlich, Hardwaregeräte zu initialisieren, bevor sie verwendet werden können. Wenn es kein Betriebssystem und keinen Bootloader gibt, ist dies Ihr Code, der dies tut. Sie müssen sich daran erinnern, dass Konstruktoren für globale Objekte ausgeführt werden, bevor sie
main()
aufgerufen werden. Daher müssen Sie Ihre lokale CRT0.S (oder eine entsprechende Entsprechung) ändern, um die Hardware-Initialisierung durchzuführen, bevor die globalen Konstruktoren selbst aufgerufen werden. Offensichtlich ist die Spitzemain()
viel zu spät.quelle
Nein. Alle C ++ - Sprachfunktionen, die Probleme verursachen können (Laufzeitpolymorphismus, RTTI usw.), können während der eingebetteten Entwicklung vermieden werden. Es gibt eine Community von eingebetteten C ++ - Entwicklern (ich erinnere mich, dass ich Spalten von eingebetteten Entwicklern gelesen habe, die C ++ im alten C / C ++ - Benutzerjournal verwendet haben), und ich kann mir nicht vorstellen, dass sie sehr lautstark wären, wenn die Wahl so schlecht wäre.
quelle
Der technische Bericht zur C ++ - Leistung ist ein guter Leitfaden für diese Art von Dingen. Beachten Sie, dass es einen Abschnitt zu Problemen mit der eingebetteten Programmierung gibt!
Auch ++ zur Erwähnung von Embedded C ++ in den Antworten. Der Standard entspricht nicht zu 100% meinem Geschmack, ist jedoch eine gute Referenz, wenn Sie entscheiden, welche Teile von C ++ Sie löschen möchten.
Während der Programmierung für kleine Plattformen deaktivieren wir Ausnahmen und RTTI, vermeiden virtuelle Vererbung und achten genau auf die Anzahl der virtuellen Funktionen, die wir herumliegen.
Ihr Freund ist jedoch die Linker-Map: Überprüfen Sie sie regelmäßig, und Sie werden feststellen, dass Codequellen und statischer Speicher schnell aufblähen.
Danach gelten die Standardüberlegungen zur dynamischen Speichernutzung: In einer Umgebung, die so eingeschränkt ist wie die von Ihnen erwähnte, möchten Sie möglicherweise überhaupt keine dynamischen Zuordnungen verwenden. Manchmal können Sie mit Speicherpools für kleine dynamische Zuordnungen oder einer "rahmenbasierten" Zuweisung davonkommen, bei der Sie einen Block vorab zuweisen und das Ganze später wegwerfen.
quelle
Ich empfehle die Verwendung des C ++ - Compilers, schränke jedoch die Verwendung von C ++ - spezifischen Funktionen ein. Sie können wie C in C ++ programmieren (die C-Laufzeit ist in C ++ enthalten, obwohl Sie in den meisten eingebetteten Anwendungen die Standardbibliothek sowieso nicht verwenden).
Sie können einfach C ++ - Klassen usw. verwenden
quelle
Als Firmware- / Embedded-System-Ingenieur kann ich Ihnen einige Gründe nennen, warum C immer noch die erste Wahl gegenüber C ++ ist, und ja, ich spreche beide fließend.
1) Einige Ziele, auf denen wir entwickeln, verfügen über 64 KB RAM für Code und Daten. Sie müssen also sicherstellen, dass jede Byte zählt. Ja, ich habe mich mit der Codeoptimierung befasst, um 4 Bytes zu sparen, die mich 2 Stunden gekostet haben 2008.
2) Jede C-Bibliotheksfunktion wird aufgrund der Größenbeschränkung überprüft, bevor wir sie in den endgültigen Code aufnehmen. Daher bevorzugen wir, dass Benutzer nicht dividieren (kein Hardware-Teiler, daher wird eine große Bibliothek benötigt), malloc (weil wir keinen Heap haben) verwenden Der gesamte Speicher wird aus dem Datenpuffer in einem 512-Byte-Block zugewiesen und muss auf Code überprüft werden. Denken Sie daran, dass jede Bibliotheksfunktion, die Sie verwenden, zählt.
3) Schon mal was von dem Begriff Overlay gehört? Sie haben so wenig Code-Speicherplatz, dass Sie manchmal Dinge mit einem anderen Code-Satz austauschen müssen. Wenn Sie eine Bibliotheksfunktion aufrufen, muss die Bibliotheksfunktion resident sein. Wenn Sie es nur in einer Überlagerungsfunktion verwenden, verschwenden Sie viel Platz, wenn Sie zu viele objektorientierte Methoden verwenden. Nehmen Sie also keine C-Bibliotheksfunktion an, geschweige denn, dass C ++ akzeptiert wird.
4) Casting und sogar Packen (wenn die nicht ausgerichtete Datenstruktur die Wortgrenze überschreitet) sind aufgrund des eingeschränkten Hardware-Designs (dh einer ECC-Engine, die auf eine bestimmte Weise verkabelt ist) oder zur Bewältigung eines Hardware-Fehlers erforderlich. Sie können nicht zu viel implizit annehmen. Warum sollten Sie es also zu sehr objektorientieren?
5) Worst-Case-Szenario: Wenn Sie einige der objektorientierten Methoden eliminieren, müssen Sie überlegen, bevor Sie Ressourcen verwenden, die explodieren können (dh 512 Bytes auf einem Stapel anstatt aus einem Datenpuffer zuweisen), und einige der potenziellen Worst-Case-Szenarien verhindern werden nicht auf den gesamten Codepfad getestet oder eliminiert.
6) Wir verwenden viel Abstraktion, um Hardware von Software fernzuhalten und Code so portabel wie möglich und simulationsfreundlich zu machen. Der Hardwarezugriff muss in eine Makro- oder Inline-Funktion eingebunden sein, die bedingt zwischen verschiedenen Plattformen kompiliert wird. Der Datentyp muss als Bytegröße und nicht als zielspezifische Umwandlung umgewandelt werden. Eine direkte Zeigerverwendung ist nicht zulässig (da einige Plattformen davon ausgehen, dass die zugeordnete Speicher-E / A die ist wie Datenspeicher) usw.
Ich kann mir mehr vorstellen, aber Sie haben die Idee. Wir Firmware-Leute haben zwar objektorientiertes Training, aber die Aufgabe des eingebetteten Systems kann so hardwareorientiert und niedrig sein, dass es von Natur aus nicht hoch oder abstrakt ist.
Übrigens, jeder Firmware-Job, bei dem ich gearbeitet habe, verwendet die Quellcodeverwaltung. Ich weiß nicht, woher Sie diese Idee haben.
-Einiger Firmware-Typ von SanDisk.
quelle
Warum sagen die Leute das? Sie wissen nicht , was jede Zeile von C tut, es sei denn, Sie überprüfen die ASM-Ausgabe. Gleiches gilt für C ++.
Was bringt diese unschuldige Aussage zum Beispiel hervor:
Es sieht ziemlich unschuldig aus, aber ein gcc-basierter Compiler erzeugt diesen Asm für ein 8-Bit-Mikro
Die Anzahl der erstellten Anweisungen hängt massiv ab von:
Dies gilt insbesondere in der winzigen eingebetteten Welt, in der Prozessoren einfach nicht für C eingerichtet sind. Meine Antwort wäre also, dass C und C ++ genauso schlecht sind wie die anderen, es sei denn, Sie untersuchen immer die asm-Ausgabe, in diesem Fall sind genauso gut wie die anderen.
Hugo
quelle
Ich habe gehört, dass einige Leute C für eingebettete Arbeit bevorzugen, weil es einfacher ist und daher einfacher ist, den tatsächlich generierten Code vorherzusagen.
Ich persönlich würde denken, dass das Schreiben von C ++ im C-Stil (Verwendung von Vorlagen für die Typensicherheit) Ihnen viele Vorteile bringen würde, und ich sehe keinen wirklichen Grund, dies nicht zu tun.
quelle
Ich sehe keinen Grund, C anstelle von C ++ zu verwenden. Was auch immer Sie in C tun können, Sie können es auch in C ++ tun. Wenn Sie den Aufwand für VMT vermeiden möchten, verwenden Sie keine virtuellen Methoden und keinen Polymorphismus.
C ++ kann jedoch einige sehr nützliche Redewendungen ohne Overhead bereitstellen. Einer meiner Favoriten ist RAII. Klassen sind nicht unbedingt teuer in Bezug auf Speicher oder Leistung ...
quelle
Ich habe Code für ARM7 Embedded Paltform auf IAR Workbench geschrieben. Ich empfehle dringend, sich auf Vorlagen zu verlassen, um die Optimierung der Kompilierungszeit und die Pfadvorhersage durchzuführen. Vermeiden Sie dynamisches Casting wie Pest. Nutzen Sie Merkmale / Richtlinien zu Ihrem Vorteil, wie in Andrei Alexandrescus Buch Modern C ++ Design beschrieben .
Ich weiß, es kann schwer zu lernen sein, aber ich bin auch sicher, dass Ihr Produkt von diesem Ansatz profitieren wird.
quelle
Ein guter Grund und manchmal der einzige Grund ist, dass es noch keinen C ++ - Compiler für das spezifische eingebettete System gibt. Dies ist beispielsweise bei Microchip PIC- Mikrocontrollern der Fall . Sie sind sehr einfach zu schreiben und haben einen kostenlosen C-Compiler (eigentlich eine leichte Variante von C), aber es ist kein C ++ - Compiler in Sicht.
quelle
Für ein System, das auf 4 KB RAM beschränkt ist, würde ich C verwenden, nicht C ++, nur damit Sie sicher sein können, alles zu sehen, was vor sich geht. Die Sache mit C ++ ist, dass es sehr einfach ist, weit mehr Ressourcen (sowohl CPU als auch Speicher) zu verwenden, als es aussieht, als würde man einen Blick auf den Code werfen. (Oh, ich werde einfach ein anderes BlerfObject erstellen, um das zu tun ... whoops! Aus dem Gedächtnis!)
Sie können dies in C ++ tun, wie bereits erwähnt (keine RTTI, keine vtables usw. usw.), aber Sie werden genauso viel Zeit damit verbringen, sicherzustellen, dass Ihre C ++ - Nutzung nicht von Ihnen abweicht, wie Sie es in C tun würden .
quelle
Der menschliche Geist befasst sich mit Komplexität, indem er so viel wie möglich bewertet und dann entscheidet, worauf es ankommt, und den Rest verwirft oder abwertet. Dies ist die gesamte Grundlage für das Branding im Marketing und vor allem für Ikonen.
Um dieser Tendenz entgegenzuwirken, ziehe ich C C ++ vor, weil es Sie dazu zwingt, über Ihren Code nachzudenken und wie er enger mit der Hardware interagiert - unerbittlich nahe.
Aus langjähriger Erfahrung glaube ich, dass C Sie dazu zwingt, bessere Lösungen für Probleme zu finden, teilweise indem Sie aus dem Weg gehen und Sie nicht dazu zwingen, viel Zeit damit zu verschwenden, eine Einschränkung zu erfüllen, die einige Compiler-Writer für eine gute Idee hielten oder herauszufinden, was "unter der Decke" los ist.
In diesem Sinne verbringen Sie bei Low-Level-Sprachen wie C viel Zeit damit, sich auf die Hardware zu konzentrieren und gute Datenstruktur- / Algorithmus-Bundles zu erstellen, während Sie bei High-Level-Sprachen viel Zeit damit verbringen, sich am Kopf zu kratzen und sich zu fragen, was dort vor sich geht und warum Sie in Ihrem spezifischen Kontext und Ihrer Umgebung nichts völlig Vernünftiges tun können. Es ist KEIN produktiver Zeitaufwand, Ihren Compiler zur Übermittlung zu zwingen (starkes Tippen ist der schlimmste Übeltäter).
Ich passe wahrscheinlich gut in die Programmierform - ich mag Kontrolle. Meiner Meinung nach ist das kein Persönlichkeitsfehler für einen Programmierer. Kontrolle ist das, wofür wir bezahlt werden. Genauer gesagt, FLAWLESSLY Kontrolle. C gibt Ihnen viel mehr Kontrolle als C ++.
quelle
Persönlich mit 4 KB Arbeitsspeicher würde ich sagen, dass Sie mit C ++ nicht viel mehr Kilometer herausholen. Wählen Sie also einfach diejenige aus, die als beste Compiler- / Laufzeitkombination für den Job erscheint, da die Sprache wahrscheinlich nicht viel ausmacht.
Beachten Sie, dass es sowieso auch nicht nur um Sprache geht, da auch die Bibliothek wichtig ist. Oft haben C-Bibliotheken eine etwas kleinere Mindestgröße, aber ich könnte mir vorstellen, dass eine C ++ - Bibliothek, die auf die eingebettete Entwicklung abzielt, reduziert wird. Testen Sie sie also unbedingt.
quelle
C gewinnt bei der Portabilität - weil es in der Sprachspezifikation weniger mehrdeutig ist; Dies bietet eine viel bessere Portabilität und Flexibilität für verschiedene Compiler usw. (weniger Kopfschmerzen).
Wenn Sie die C ++ - Funktionen nicht nutzen möchten, um einen Bedarf zu decken, wählen Sie C.
quelle
unsigned mul(unsigned short x, unsigned short y) { return x*y;}
hat keine Nebenwirkungen, selbst wenn das Produkt 2147483647 überschreitet oder wenn esvoid get_float_bits(float *fp, uint32_t n) { *(uint32_t)fp = n; }
als mögliche Änderung des Wertes von afloat
] angesehen werden sollte.Persönlich, wenn es um eingebettete Anwendungen geht (Wenn ich Embedded sage, meine ich heute nicht winCE, iPhone usw. aufgeblähte eingebettete Geräte). Ich meine ressourcenbeschränkte Geräte. Ich bevorzuge C, obwohl ich auch ziemlich viel mit C ++ gearbeitet habe.
Das Gerät, über das Sie sprechen, verfügt beispielsweise über 4 KB RAM. Aus diesem Grund würde ich C ++ nicht in Betracht ziehen. Sicher, Sie sind möglicherweise in der Lage, mit C ++ etwas Kleines zu entwerfen und die Verwendung in Ihrer Anwendung einzuschränken, wie andere Beiträge vorgeschlagen haben, aber C ++ "könnte" möglicherweise dazu führen, dass Ihre Anwendung unter dem Deckmantel kompliziert / aufgebläht wird.
Wirst du statisch verlinken? Möglicherweise möchten Sie eine statische Dummy-Anwendung mit c ++ mit c vergleichen. Das kann dazu führen, dass Sie stattdessen C in Betracht ziehen. Wenn Sie jedoch in der Lage sind, eine C ++ - Anwendung innerhalb Ihrer Speicheranforderungen zu erstellen, entscheiden Sie sich dafür.
IMHO, Im Allgemeinen möchte ich in eingebetteten Anwendungen alles wissen, was vor sich geht. Wer verwendet Speicher- / Systemressourcen, wie viel und warum? Wann befreien sie sie?
Bei der Entwicklung für ein Ziel mit einer X-Menge an Ressourcen, CPU, Speicher usw. versuche ich, bei der Verwendung dieser Ressourcen auf der unteren Seite zu bleiben, da Sie nie wissen, welche zukünftigen Anforderungen sich ergeben werden, sodass Sie dem Projekt mehr Code hinzufügen müssen sollte eine einfache kleine Anwendung sein, wird aber viel größer.
quelle
Meine Wahl wird normalerweise von der C-Bibliothek bestimmt, die wir verwenden möchten. Diese wird basierend auf den Anforderungen des Geräts ausgewählt. Also, 9/10 mal ... es endet mit uclibc oder newlib und C. Der Kernel, den wir verwenden, hat auch einen großen Einfluss darauf, oder wenn wir unseren eigenen Kernel schreiben.
Es ist auch eine Wahl der Gemeinsamkeiten. Die meisten guten C-Programmierer haben kein Problem mit C ++ (obwohl sich viele die ganze Zeit über beschweren, dass sie es verwenden). Aber ich habe nicht festgestellt, dass das Gegenteil der Fall ist (meiner Erfahrung nach).
In einem Projekt, an dem wir arbeiten (das einen Grundkern beinhaltet), werden die meisten Dinge in C erledigt, jedoch wurde ein kleiner Netzwerkstapel in C ++ implementiert, da es einfach und weniger problematisch war, Netzwerke mit C ++ zu implementieren.
Das Endergebnis ist, dass das Gerät entweder funktioniert und Abnahmetests besteht oder nicht. Wenn Sie foo in xx-Stapel- und yy-Heap-Einschränkungen mit der Sprache z implementieren können, wählen Sie alles, was Sie produktiver macht.
Meine persönliche Präferenz ist C, weil:
Ja, ich bin mit C ++ vertraut, aber ich weiß es nicht so gut wie Standard C.
Wenn Sie das Gegenteil sagen können, verwenden Sie das, was Sie wissen :) Wenn es funktioniert, Tests besteht usw. Was ist das Problem?
quelle
Wie viel ROM / FLASH hast du?
4 KB RAM können immer noch bedeuten, dass Hunderte von Kilobyte FLASH zum Speichern des tatsächlichen Codes und der statischen Daten vorhanden sind. RAM in dieser Größe ist in der Regel nur für Variablen gedacht, und wenn Sie mit diesen vorsichtig sind, können Sie ein ziemlich großes Programm in Bezug auf Codezeilen in den Speicher einfügen.
C ++ erschwert jedoch das Einfügen von Code und Daten in FLASH aufgrund der Laufzeitkonstruktionsregeln für Objekte. In C kann eine konstante Struktur leicht in den FLASH-Speicher gestellt und als hardwarekonstantes Objekt aufgerufen werden. In C ++ würde ein konstantes Objekt erfordern, dass der Compiler den Konstruktor zur Kompilierungszeit auswertet, was meiner Meinung nach immer noch über das hinausgeht, was ein C ++ - Compiler kann (theoretisch könnte man es tun, aber in der Praxis ist es sehr, sehr schwierig). .
In einer Umgebung mit "kleinem RAM" und "großem FLASH" würde ich jeden Tag mit C arbeiten. Beachten Sie, dass i C99 eine gute Zwischenauswahl ist, die die meisten netten C ++ - Funktionen für nicht klassenbasierten Code bietet.
quelle
Im Allgemeinen nein. C ++ ist eine super Menge von C. Dies gilt insbesondere für neue Projekte.
Sie sind auf dem richtigen Weg, um C ++ - Konstrukte zu vermeiden, die in Bezug auf CPU-Zeit und Speicherbedarf teuer sein können.
Beachten Sie, dass einige Dinge wie Polymorphismus sehr wertvoll sein können - das sind im Wesentlichen Funktionszeiger. Wenn Sie feststellen, dass Sie sie brauchen, setzen Sie sie mit Bedacht ein.
Eine gute (gut gestaltete) Ausnahmebehandlung kann Ihre eingebettete App zuverlässiger machen als eine App, die Dinge mit herkömmlichen Fehlercodes behandelt.
quelle
Bei Problemen mit der Speicherzuweisung kann ich die Verwendung der Quantum Platform und ihres Zustandsmaschinenansatzes empfehlen, da sie alles zuweist, was Sie zum Zeitpunkt der Initialisierung benötigen. Es hilft auch, Konfliktprobleme zu lindern.
Dieses Produkt läuft sowohl unter C als auch unter C ++.
quelle
Einige sagen, dass C-Compiler viel effizienteren Code generieren können, da sie die erweiterten C ++ - Funktionen nicht unterstützen müssen und daher bei ihren Optimierungen aggressiver sein können.
In diesem Fall möchten Sie natürlich die beiden spezifischen Compiler testen.
quelle
Der einzige Grund, C IMHO zu bevorzugen, wäre, wenn der C ++ - Compiler für Ihre Plattform nicht in einem guten Zustand ist (fehlerhaft, schlechte Optimierung usw.).
quelle
Das Buch C ++ für Spielprogrammierer enthält Informationen darüber, wann die Codegröße basierend auf Funktionen aus C ++ erhöht wird.
quelle
Sie haben Inline in C99. Vielleicht magst du ctors, aber das Geschäft, dtors richtig zu machen, kann chaotisch sein. Wenn der verbleibende einzige Grund, C nicht zu verwenden, Namespaces sind, würde ich mich wirklich an C89 halten. Dies liegt daran, dass Sie es möglicherweise auf eine etwas andere eingebettete Plattform portieren möchten. Sie können später in C ++ mit demselben Code schreiben. Beachten Sie jedoch Folgendes: C ++ ist KEINE Obermenge von C. Ich weiß, dass Sie gesagt haben, Sie haben einen C89-Compiler, führt diesen C ++ - Vergleich jedoch trotzdem mit C99 durch, da das erste Element beispielsweise für jedes C seit K & R gilt.
Größe von 'a' > 1 in C, nicht in C ++. In C haben Sie VLA-Arrays mit variabler Länge. Beispiel: func (int i) {int a [i] . In C haben Sie VAM-Variablenarray-Mitglieder. Beispiel: struct {int b; int m [];} .
quelle
Das hängt vom Compiler ab.
Nicht alle eingebetteten Compiler implementieren C ++ vollständig, und selbst wenn dies der Fall ist, können sie möglicherweise das Aufblähen von Code nicht gut vermeiden (was bei Vorlagen immer ein Risiko darstellt). Testen Sie es mit einigen kleineren Programmen, um festzustellen, ob Probleme auftreten.
Aber angesichts eines guten Compilers gibt es keinen Grund, C ++ nicht zu verwenden.
quelle
Ich möchte nur sagen, dass es kein System mit "UNBEGRENZTEN" Ressourcen gibt. Alles auf dieser Welt ist begrenzt und JEDE Anwendung sollte die Ressourcennutzung berücksichtigen, unabhängig davon, ob es sich um ASM, C, JAVA oder JavaScript handelt. Die Dummies, die ein paar Mbs "nur um sicher zu gehen" zuweisen, machen iPhone 7, Pixel und andere Geräte extrem träge. Egal ob Sie 4kb oder 40 Gb haben.
Aber von einer anderen Seite, um sich der Verschwendung von Ressourcen zu widersetzen, ist eine Zeit erforderlich, um diese Ressourcen zu schonen. Wenn es 1 Woche länger dauert, eine einfache Sache in C zu schreiben, um ein paar Ticks und ein paar Bytes zu sparen, anstatt C ++ zu verwenden, das bereits implementiert, getestet und verteilt wurde. Warum die Mühe? Es ist wie der Kauf eines USB-Hubs. Ja, du kannst es selbst machen, aber wird es besser? zuverlässiger? billiger, wenn Sie Ihre Zeit zählen?
Nur ein Nebengedanke - selbst die Stromversorgung Ihrer Steckdose ist nicht unbegrenzt. Versuchen Sie herauszufinden, woher es kommt, und Sie werden hauptsächlich sehen, dass es etwas verbrennt. Das Gesetz von Energie und Material gilt weiterhin: Es erscheint oder verschwindet kein Material oder keine Energie, sondern wandelt sich um.
quelle
Ich habe gerade ein Beispiel für die Verwendung von ISO C ++ für die eingebettete Entwicklung gefunden, das für jemanden interessant sein könnte, der die Entscheidung trifft, wann immer er C ++ oder C verwendet.
Es wurde von Bjarne Stroustrup auf seiner Homepage zur Verfügung gestellt :
Einen Blick darauf, wie ISO C ++ für die ernsthafte Programmierung eingebetteter Systeme verwendet werden kann, finden Sie in den C ++ - Codierungsstandards für JSF-Luftfahrzeuge .
quelle
Unterschiedlicher Antwortbeitrag zu einem anderen Aspekt der Frage:
"malloc"
Einige frühere Antworten sprechen ziemlich viel darüber. Warum glaubst du überhaupt, dass dieser Anruf existiert? Für eine wirklich kleine Plattform ist malloc in der Regel nicht verfügbar oder definitiv optional. Die Implementierung einer dynamischen Speicherzuweisung ist in der Regel sinnvoll, wenn Sie ein RTOS im unteren Bereich Ihres Systems haben - bis dahin ist dies jedoch rein gefährlich.
Ohne kann man sehr weit kommen. Denken Sie nur an all die alten FORTRAN-Programme, die nicht einmal einen richtigen Stapel für lokale Variablen hatten ...
quelle
Es gibt eine Reihe verschiedener Controller-Hersteller auf der ganzen Welt. Wenn Sie sich deren Design und die Befehlssätze ansehen, die für die Konfiguration verwendet werden müssen, kann dies zu vielen Problemen führen. Der Hauptnachteil der Assemblersprache ist, dass die Maschine / Architektur abhängig ist. Es ist wirklich eine große Herausforderung für einen Entwickler, alle dort aufgeführten Anweisungen auswendig zu lernen, um die Codierung für verschiedene Controller durchzuführen. Aus diesem Grund wurde C in der Embedded-Entwicklung immer beliebter, da C hoch genug ist, um die Algorithmen und Datenstrukturen von hardwareabhängigen Details zu abstrahieren, wodurch der Quellcode auf eine Vielzahl von Zielhardware, architekturunabhängiger Sprache und sehr einfach zu portieren ist Konvertieren und pflegen Sie den Code. Wir sehen jedoch einige (objektorientierte) Hochsprachen wie C, C ++, Python, Java usw.
quelle
Ich empfehle C ++ mit Einschränkungen und Hinweisen.
Time-to-Market und Wartbarkeit. Die C ++ - Entwicklung ist einfacher und schneller. Wenn Sie sich also in der Entwurfsphase befinden, wählen Sie einen Controller, der groß genug ist, um C ++ zu verwenden. (Beachten Sie, dass ein Markt mit hohem Volumen so niedrige Kosten wie möglich erfordert, wenn Sie diese Wahl nicht treffen können.)
Geschwindigkeit. C kann schneller als C ++ sein, aber stellen Sie sicher, dass der Geschwindigkeitsgewinn nicht groß ist. Sie können also mit C ++ gehen. Entwickeln Sie Ihre Algorithmen, testen Sie sie und beschleunigen Sie sie nur bei Bedarf (!). Verwenden Sie Profiler, um die Engpässe zu erkennen und sie extern "C" umzuschreiben , um die C-Geschwindigkeit zu erreichen. (Wenn es diesen Teil immer noch langsam implementiert, implementieren Sie ihn in ASM.)
Binärgröße. Die C ++ - Codes sind größer, aber hier ist eine großartige Antwort , die die Details verrät. Die Größe der kompilierten Binärdatei eines bestimmten C-Codes ist gleich, unabhängig davon, ob sie mit dem C- oder dem C ++ - Compiler kompiliert wurde. "Die Größe der ausführbaren Datei hängt kaum von der Sprache ab, sondern von den Bibliotheken, die Sie in Ihr Projekt aufnehmen." Gehen Sie mit C ++ , aber vermeiden erweiterte Funktionen, wie
streams
,string
,new
,virtual
Funktionen etc. Überprüfen Sie alle Bibliotheksfunktion , bevor sie in den endgültigen Code zu lassen, weil der Größenbeschränkung (basierend auf dieser Antwort)quelle