Hey Leute, ich habe eine Frage an euch bzw würde gerne eure Erfahrungen hören! Heute behauptete ein Bekannter von mir das man Mikrocontroller besser mit C++ programmieren kann als in C. Auf meine Frage warum das so sei, sagte er das man in C++ quasi mehr und präzisere Werkzeuge habe als mit reinem C. Da ich bisher nur in C programmiert habe und mich mit C++ nicht gut auskenne, würde ich gerne ein Paar Meinungen dazu hören. Danke :)
Es kommt hauptsächlich darauf an wer programmiert. Die Programmiersprache ist an und für sich wurscht.
Hat eine gewisse Sprache denn Vorteile gegenüber der anderen?
Da C++ bis auf wenige Ausnahmen auch alle Features von C enhält und dazu noch einen Haufen neuer Features, ist C++ deutlich mächtiger (und komplizierter). Wenn man weiß wie man mit den neuen Features umgeht und welche davon auch für Mikrocontroller geeignet sind dann sehe ich in der Verwendung von C++ auf Mikrocontrollern eigentlich nur Vorteile. Wobei jetzt auch wieder einige Leute behaupten werden, dass nur das "erste" C nach K&R (oder Assembler) das einzig Wahre ist.
Ja sicher, jede der beiden Sprachen hat Vorteile gegenüber der anderen, nur halt andere. C ist auf alle Fälle einfacher. C++ hat mächtige Werkzeuge zur Abstraktion (templates).
Das Thema ist nicht neu: Beitrag "C++ auf einem MC, wie geht das?" Beitrag "AVR und C++ - ein Versuch"
Du kannst in C fast alle Features des Mikrocontrollers voll ausnutzen. In C++ ebenfalls. In Assembler kannst du alle Features ausnutzen. Ich würde trotzdem C oder C++ bevorzugen, soweit möglich. Ein korrektes C Programm ist nicht schlechter als das selbe Programm in C++ Programm. Man kann daher nicht pauschal sagen, welche Sprache besser ist. Deine Frage ist in etwas wie: Was ist besser, ein gewöhnlicher Hammer oder ein Dachdecker-Hammer? Zum Nägel in die Wand treiben eignen sich beide gleich gut.
Sebastian V. schrieb: > Da C++ bis auf wenige Ausnahmen auch alle Features von C enhält und dazu > noch einen Haufen neuer Features, ist C++ deutlich mächtiger (und > komplizierter). Wenn man weiß wie man mit den neuen Features umgeht und > welche davon auch für Mikrocontroller geeignet sind dann sehe ich in der > Verwendung von C++ auf Mikrocontrollern eigentlich nur Vorteile. Wobei > jetzt auch wieder einige Leute behaupten werden, dass nur das "erste" C > nach K&R (oder Assembler) das einzig Wahre ist. Das ist eigentlich ganz simpel: je höher der Abstraktionsgrad der Sprache, desto mehr kann sie für einen tun (wenn man sie beherrscht natürlich nur). Der Nachteil ist aber auch (zumindest tendentiell) immer, dass sie dazu zur Laufzeit für das gleiche Problem mehr Resourcen erfordern wird als eine weniger abstrakte Sprache. C++ vs. C, ist ein sehr schönes Beispiel für dieses Prinzip (was sich im übrigen ganz zwanglos aus den Grundgesetzen der Informatik herleiten läßt). C++ kann (bezüglich des Ressourcenbedarfs) immer genau dann gerade so mit C mithalten, wenn man auf die tatsächlich vorteilhaften Features von C++ komplett verzichtet... Tendenziell ähnlich, aber doch im Detail durchaus anders ist es bei C vs. Asm. Da kann C gerade so mit Asm mithalten, wenn man zumindest an den kritischen Stellen auf die vorteilhaften Features von C verzichtet. Was allerdings in diesem Fall zumindest gelegentlich bedeutet, gleich ganz auf C verzichten zu müssen, weil der Impact des verbleibenden Rests einfach viele sinnvolle Optimierungen an den wirklich kritischen Stellen nicht zuläßt oder zumindest erheblich schwerer macht.
c-hater schrieb: > wenn man auf die tatsächlich vorteilhaften > Features von C++ komplett verzichtet... Was ist mit den Features die zur Compilezeit ausgeführt werden?
Probiere C++ aus, aber hüte Dich davor, globale, reale Hardware (IO) unbedingt in OOP zwängen zu wollen. Vermeide RTTI und hüte Dich vor sorglosem Umgang mit Exceptions. Die sind oftmals nur dann sinnvoll, wenn ein kognitiver Benutzer eingreifen kann. c-hater schrieb: > Tendenziell ähnlich, aber doch im Detail durchaus anders ist es bei C > vs. Asm. Da kann C gerade so mit Asm mithalten, wenn man zumindest an > den kritischen Stellen auf die vorteilhaften Features von C verzichtet. > Was allerdings in diesem Fall zumindest gelegentlich bedeutet, gleich > ganz auf C verzichten zu müssen, weil der Impact des verbleibenden Rests > einfach viele sinnvolle Optimierungen an den wirklich kritischen Stellen > nicht zuläßt oder zumindest erheblich schwerer macht. Das stimmt einfach nicht. Der Unterschied zwischen C und Assembler ist wie der zwischen Schreibmaschine und Textverarbeitung. Wenn ich ein Programm oder eine Funktion genau einmal brauche und runterhacke, dann kann Assembler effektiver sein. Der C-Compiler schlägt den Assembler aber, wenn - strukturiert, lesbar, wiederverwendbar programmiert wird - ich nicht alle Tricks und Kniffe zur Optimierung kenne - ich die Opcodes und deren Dauer nicht genau im Kopf habe - wenn der Code sich fleißig ändert (und ich nicht jede Zeile neu optimiere) Zudem ist C um Größenordnungen produktiver bei Plattformwechseln oder Verwendung von externem Code. Brächte C++ auch nur einen Bruchteil dieser Effektivitätssteigerung gegenüber C im Low-Level-Bereich (OS, µC, Safety, konkrete IO), dann wäre der Linux-Kernel seit 10 Jahren auf C++ portiert und C wäre ein Exot. Auf der anderen Seite wäre Assembler schon 20 Jahre bedeutungslos, wenn heutige C-Compiler für Pics, Avrs und Co schon damals verfügbar gewesen wären. Bei C++ ist das kein limitierender Faktor. Es macht einfach wenig Sinn, die unbestreitbaren Vorteile der OOP oder Funktionalen Programmierung bei virtuellen Objekten (GUIs, Datensätze, Webseiten, allgemeine Interfaces) auf dedizierte zu kontrollierende Objekte zu übertragen. Genau wie es einige Jahre dauerte, die guten gotos aus der Masse der schlechten herauszuschälen, dauert es noch ein paar Jahre, die guten globalen Variablen prozeduraler Verarbeitung aus der Masse des Spaghetticodes herauszufiltern.
Simon schrieb: > Auf meine Frage warum das so sei, sagte er das man in C++ quasi mehr und > präzisere Werkzeuge habe als mit reinem C. Man hat mehr Werkzeuge, ja. Aber man muß in C++ dafür ein besserer Programmierer sein als für reines C. Der Grund ist, daß man für C++ nicht nur wissen muß, wie man welche Features nutzt, sondern man muß auch sehr gut verstanden haben, was "unter der Haube" bei C++ abgeht und welche Features man daher nicht benutzen darf. Und dann muß man auch mit dem eingeschränkten Set an Features in C++ immer noch gut sein. Wenn man das alles kann und die deutlich zahlreicheren C++-Fallstricke meidet (die auf dem PC keine Rolle spielen), dann ist C++ weder langsamer noch ressourcenintensiver. Dummerweise sind C++-Programmierer, die das können, dann auch entsprechend teurer als C-Programmierer, die ein funktional gleichwertiges Programm erstellen können. Eben weil solche C++-Programmierer auch deutlich komplexere Jobs anderswo mit besserer Bezahlung haben können. Kommerziell spricht das gegen C++. Ich persönlich finde C++ eher hinderlich, weil man zwar die höhere Abstraktion hat, aber man muß dauernd durch sie hindurchsehen und zu Fuß zuende denken, anstatt sie einfach so zu nutzen. Wodurch für mein Empfinden der Compiler mir eher im Weg steht. Das ist aber nur meine persönliche Meinung, das werden andere anders sehen. In C++-Kreisen ist diese Einstellung nämlich als "C hacker syndrome" verpönt. Andererseits kannst Du bei zertifizierten Projekten nunmal nicht haufenweise Libraries einbinden wie auf dem PC, so daß man bei sowas mit dem "C hacker syndrome" schon gut aufgehoben ist. Bei C gibt es relativ wenig, was man meiden sollte. Sämtliche dynamische Speicherverwaltung mit malloc sollte man unterlassen, und man sollte sich über den enormen Ressourcenbedarf von printf und Konsorten bewußt sein. De facto ist C++ auf Microcontrollern eher ein C+. C mit Klassen, mehr oder weniger. Es sei denn, man geht auf die großen Cortex-A, wo ein volles Linux drunterläuft, das ist dann aber auch schon eher Applikationsprogrammierung.
Du kannst sogar auf einem 8-Bit Mikrocontroller C++ mit ein paar 100 Bytes Ram benutzen, wenn Du weißt, was Du tust und auf einige Schlüsselfeatures von C++ verzichtest. Dynamische Allokation am Heap oder Polymorphie solltest Du gleich vergessen. C++ auf MC ist ganz anders zu benutzen als in der PC-Programmierung oder so. Und Techniken, die Du von Java vielleicht kennst, sowieso. Dagegen statische Template-Klassen mit Wertparametern sind sehr OK. Allerdings musst Du wissen, was passiert. D.h. du musst es so machen, dass keine Codereplikation passiert und z.B. explizite Template-Instanziierung benutzen. Wenn Du nicht genau weißt, was C++ ist, und was der Compiler aus Deinem Code macht, dann programmiere lieber in C. Objektorientierung kannst Du auch in C - dann halt explizit ausprogrammiert. Das mach ich z.B. dann auch, wenn MISRA-C gefordert ist. S.
Sebastian V. schrieb: > Was ist mit den Features die zur Compilezeit ausgeführt werden? Das sind letztlich nichts anderes als Macros, wie man sie auch in C oder sogar Asm haben kann. Ist nur eine Frage des Geschicks bei der Macro-Programmierung. Klar: wenn man C++ benutzt, spart man diese Macroprogrammierung. Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN. Man muss dann nämlich ganz genau wissen, wie der C++-Compiler seine Syntaxblähungen umsetzt. Dieser Zustand ist keinesfalls leichter zu erreichen, als wenn man die Macros gleich selbst verfasst... Bei selbst verfassten Macros hat man nämlich einen relativ leicht nachvollziehbaren Quelltext vorliegen. Bei dem Kram, den der Compiler tut, ist man auf eine meist unzureichende, ziemlich veraltete (aber trotzdem überaus längliche) Dokumentation allein der Wirkungen fremden Codes angewiesen... Wer sich das freiwillig antut, nur um einen AVR8 in C++ zu programmieren, ohne gegenüber C nennenswerte Performancenachteile zu erleiden, der ist in meinen Augen nicht ganz sauber in der Rübe. Assembler lernen wäre sehr viel sinnvoller. Denn wenn man das wirklich kann, kann man gegenüber C massive Performancevorteile erringen. Der Aufwand hat sich dann wenigstens gelohnt, weil er einen messbaren Vorteil bringt, wohingegen dieser C++-Desingtime-Kram doch eher eine rein akademische Machbarkeitstudie darstellt. Brotlose Kunst... Sieht man ja im parallel laufenden Thread (läuft der noch?). Der Code ist in der Lage, ohne nennenswerte Verluste gegenüber C auf EINER ganz konkreten Maschine zu laufen. Na wenn das kein Erfolg ist... In C oder Assembler ist es ziemlich leicht, den Code für große Teile der gesamten Zielarchitektur lauffähig zu machen. Ich bin gespannt, wie weit dieser C++-ler kommt und vor allem darauf, wieviel dann von dem Ansatz überbleibt, mit den Sprachmitteln von C++ Code zu erzeugen, der zur Laufzeit zumindest so effizient wie C ist... Vermutlich wird es auf eine Lösung á la Arduino hinauslaufen: 100+ Takte, um einen Pin zu togglen...
Jeder Thread mit diesem Thema artet früher oder später aus :-( Leider! Es werden persönliche Angriffe losgelassen, das kann ich nicht verstehen. Jeder soll das so machen wie er möchte! Ich erkenne an, dass bei Assembler manches vllt schneller (Laufzeit) geht. Aber sicher nicht plattform-neutral. Und ich erkenne auch an, dass man C-Code man eben schnell hingeschrieben hat, um eine Led blinken zu lassen. Mit C++ kann man ein Niveau erreichen, was fast an plattform-Neutralität grenzt. Beides muss man gegeneinander abwägen, aber nicht niedermachen. Ich gebe allerdings zu bedenken, dass man mit (statischer) parametrischer Polymorphie (aka templates in C++) und vielen anderen tollen neuen(!!!) features von C++ (v.a. variadische templates und constexpr functions) unwahrscheinlich nah an der Code-Größe und Performance von Assembler dran ist. Als nächstes sehe ich dann den Punkt Wartbarkeit als ganz wichtiges. Jeder mit einem Kenntnisstand von C++98 sollte der Fairness halber einfach mal C++14/C++17/C++20 Code ansehen und probieren (auf dem Host oder uC: der avr-gcc >= 6.2 machts möglich bzw. clang++/g++ auf dem Host). Und ja, wer sonst auch in C++ programmiert und dort auch große Software-Artefakte außerhalb der uC Welt erstellt, dem fällt es natürlich leichter auch auf dem uC damit klar zu kommen. Ein Java oder Python Mensch hat es da schon wesentlich schwerer. Will sagen: ein vorgebildeter C++-Programmier hat vllt schneller etwas in C++ hingeschrieben als jemand anderes in asm oder C. VG Wilhelm
c-hater schrieb: > Sebastian V. schrieb: > >> Was ist mit den Features die zur Compilezeit ausgeführt werden? > > Das sind letztlich nichts anderes als Macros, wie man sie auch in C oder > sogar Asm haben kann. Ist nur eine Frage des Geschicks bei der > Macro-Programmierung. > > Klar: wenn man C++ benutzt, spart man diese Macroprogrammierung. > > Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN. Typsicherheit. > Vermutlich wird es auf eine Lösung á la Arduino hinauslaufen: 100+ > Takte, um einen Pin zu togglen... Das ist so ziemlich das schlechteste Beispiel, das es gibt, und natürlich hast Du es mit großem Bedacht gewählt. Arduino ist entwickelt worden, um es Leuten ohne technischen Hintergrund zu ermöglichen, möglichst einfach und ohne größeren Lernaufwand fertige Mikrocontrollerplatinen zu programmieren. Dabei geht es ausdrücklich nicht um Effizienz, minimale Codegröße oder gar um Softwareentwicklung für die Massenproduktion, sondern um größtmögliche Vereinfachung und maximale Fehlertoleranz. Und dabei war und ist Arduino ausgesprochen erfolgreich, ob Du es verstehen willst oder meinetwegen auch nicht.
c-hater schrieb: > Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN. Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde ich C++ jederzeit vorziehen.
Und ich würde ungern auf Templates verzichten: ich lasse lieber Code erzeugen als es selbst zu tun ;-)
:
Bearbeitet durch User
Sebastian V. schrieb: > Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde > ich C++ jederzeit vorziehen. Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren Seite.
Artur S. schrieb: > Sebastian V. schrieb: >> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde >> ich C++ jederzeit vorziehen. > > Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren > Seite. Das ist auch wieder ein schönes Beispiel dafür, dass beim Stichwort C++ jeder was dazu schreiben muss, der irgend wie mal davon gehört hat. Überladene Funktionen werden immer zur Compilerzeit anhand der Argumente ausgewählt (und um zu dieser Erkenntnis zu kommen, muss man jetzt auch nicht 10 Jahre C++ gemacht haben)! in C:
1 | IntSinD(1.3); |
2 | IntSinF(1.4f); |
in C++
1 | using intrinsics::sin; |
2 | sin(1.3); |
3 | sin(1.4f); |
Der generierte Code wird exakt der selbe sein. Es gibt Unmengen von features in C++, die überhaupt keine Laufzeitkosten haben. Z.B: - Funktionsüberladungen - namespaces - operators - nicht polymorphe Klassen - scoped enumerations - const correctness - präzisere casts - stärkere Typsicherheit - uvm. mfg Torsten
Artur S. schrieb: > Sebastian V. schrieb: >> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde >> ich C++ jederzeit vorziehen. > > Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren > Seite. na wie immmer, gesundes Halbwissen :)
Artur S. schrieb: > Sebastian V. schrieb: >> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde >> ich C++ jederzeit vorziehen. > > Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren > Seite. Mit meiner Bemerkung ging es mir um "würde ich C++ jederzeit vorziehen". Das kann man sich so absolut behauptet erst mit einem gut ausgestatteten Controller erlauben. Ob der dann sinnvoll für jede Anwendung ist steht auf einem anderen Blatt.
Torsten R. schrieb: > Es gibt Unmengen von features in C++, die alle zu erlernen und richtig anzuwenden sind! Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik aus dem Elfenbeinturm.
Findelkind schrieb: > Torsten R. schrieb: >> Es gibt Unmengen von features in C++, die > > alle zu erlernen und richtig anzuwenden sind! > Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik > aus dem Elfenbeinturm. Mmh, sowohl C als auch RISC als Architekturmerkmal stammen aus Elfenbeintürmen ...
Findelkind schrieb: > Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik > aus dem Elfenbeinturm. Das hat relativ wenig mit Hirnakrobatik zu tun. Vielmehr mit der Größe des Werkzeugkastens. Ich kann zur Lösung meiner Aufgaben auf viel mehr Sprachmittel zurück greifen. Und viele diese Sprachmittel dienen letztendlich dazu, Fehler möglichst bereits zur Compile-Zeit zu finden. Währen Du also noch dein K&R C Program debuggst, habe ich mein C++ Program schon fertig und liege schon auf der Couch und guck mir mal die neuen Sprachmittel von C++17 an ;-) Ich bin ja schon immer erstaunt, wie wenig embedded C Entwickler C99 nutzen (immerhin auch schon 17 Jahre alt). mfg Torsten
Wilhelm M. schrieb: > Ich gebe allerdings zu bedenken, dass man mit (statischer) > parametrischer Polymorphie (aka templates in C++) und vielen anderen > tollen neuen(!!!) features von C++ (v.a. variadische templates und > constexpr functions) unwahrscheinlich nah an der Code-Größe und > Performance von Assembler dran ist. Lol, was ein hohles Argument. Natürlich erzeugt der C++ wahrscheinlich effizienteren Code als der Programierer - nur gilt das eben nur für diese unnützen Funktionen und Features, die kein normaler Mensch jemals bei einem 8-bit AVR oder PIC brauchen wird- selbst bei enem ARM nicht. Und OOP bei uC - einfach lachhaft. Das kann vielleicht bei einer Ampelsteuerung oder Strassenbeleuchtung einigermassen zufriedenstellend funktionieren, aber bestimmt nicht bei schnellen Industriesteuerungen oder ähnlich anspruchsvollen Anwendungen. Liest doch mal ein bisschen über C++ - da sind so viele Situationen undefiniert, da kriegt man einen Lachkrampf schon bei oberflächlichem durchlesen. Für Windows und Buchhaltungs und Database Kram zu gebrauchen, für uC absolut keine Vorteile, ausser das man rumposaunen kann, dass es in C++ programmiert ist. Das es im Endeffekt nur auf Legosteine zusammensetzen rausläuft, wird gerne übersehen... Torsten R. schrieb: > Währen Du also noch dein K&R C Program debuggst, habe ich mein C++ > Program schon fertig und liege schon auf der Couch und guck mir mal die > neuen Sprachmittel von C++17 an ;-) Oder in irgendeinem Forum Arduino benutzer anspucken, auch wenn diese genau dasselbe machen wie du...
:
Bearbeitet durch User
c-hater schrieb: > Klar: wenn man C++ benutzt, spart man diese Macroprogrammierung. > > Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN. Doch, hat man, das Zeug ist typsicher. C-Makros sind ganz doofe Textersetzung, wenn da der Wurm drin ist kanns ganz schön umstänglich sein, das zu debuggen. > Man muss dann nämlich ganz genau wissen, wie der C++-Compiler seine > Syntaxblähungen umsetzt. Dieser Zustand ist keinesfalls leichter zu > erreichen, als wenn man die Macros gleich selbst verfasst... > > Bei selbst verfassten Macros hat man nämlich einen relativ leicht > nachvollziehbaren Quelltext vorliegen. Bei dem Kram, den der Compiler > tut, ist man auf eine meist unzureichende, ziemlich veraltete (aber > trotzdem überaus längliche) Dokumentation allein der Wirkungen fremden > Codes angewiesen... Bei selbst verfassten templates auch. Makros sind nicht automatisch leicht nachvollziehbar. Da gibts Beispiele in denen ein Makro per inline-assembler eine Shell füttert und den Output selbiger ins Programm reinnudelt. Total unverständlich. > Wer sich das freiwillig antut, nur um einen AVR8 in C++ zu > programmieren, ohne gegenüber C nennenswerte Performancenachteile zu > erleiden, der ist in meinen Augen nicht ganz sauber in der Rübe. Dass sich das niemand antut wenn er nennenswerte Performancenachteile erleiden würde ist ja klar, oder? > Assembler lernen wäre sehr viel sinnvoller. Denn wenn man das wirklich > kann, kann man gegenüber C massive Performancevorteile erringen. Der > Aufwand hat sich dann wenigstens gelohnt, weil er einen messbaren > Vorteil bringt, wohingegen dieser C++-Desingtime-Kram doch eher eine > rein akademische Machbarkeitstudie darstellt. Brotlose Kunst... Da lernt man dann eine Architektur, und bei der nächsten ist alles ganz anders. Davon abgesehen sind z.B. die ARMs recht mühsam in ASM zu programmieren, abgesehen davon ist es Wahnsinn, einige zig Kilobyte an Maschinencode in Assembler zu erstellen. > In C oder Assembler ist es ziemlich leicht, den Code für große Teile der > gesamten Zielarchitektur lauffähig zu machen. Ich bin gespannt, wie weit > dieser C++-ler kommt und vor allem darauf, wieviel dann von dem Ansatz > überbleibt, mit den Sprachmitteln von C++ Code zu erzeugen, der zur > Laufzeit zumindest so effizient wie C ist... In C++ lässt sich ohne weiteres Code erstellen, der effizienter als äquivalenter C-Code läuft, dabei kürzer und weniger fehleranfällig ist. Die Leute, die C++ kategorisch ablehnen, tun das meistens nur deswegen, weil sie einfach aus Prinzip nichts Neues (mehr) anfangen wollen. Sollen sie halt weiter in ihrem 1er Golf herumfahren, während der Stand der Technik längst Airbags, Vollverzinkung, Kat, dabei 3mal so viel Motorleistung bei weniger Verbrauch ist. Funktionsüberladungen, templates, namespaces, überladene operatoren, inline-Funktionen, lambdas, static_assert, "RAII" etc. machen Code übersichtlicher, korrekter, wartbarer, und haben keine negativen Auswirkungen auf Laufzeit oder Codesize im Vergleich zu C, vorausgesetzt die/der Author/in weiss was man tut. Eine nicht-vollständige Liste wo C++ auch auf Mikrokontrollern massiv Sinn macht: mit "Policies" kann man die Quellen auf eine Art und Weise entkoppeln und gleichzeitig doch zur Compilezeit binden, wie das in C nur durch eine Art Meta-Compiler möglich wäre und/oder zur Laufzeit umständlichen und kostspieligen Funktionspointer-Overhead hätte.
c-hater schrieb: > Man muss dann nämlich ganz genau wissen, wie der C++-Compiler seine > Syntaxblähungen umsetzt. Dieser Zustand ist keinesfalls leichter zu > erreichen, als wenn man die Macros gleich selbst verfasst... > > Bei selbst verfassten Macros hat man nämlich einen relativ leicht > nachvollziehbaren Quelltext vorliegen. Bei dem Kram, den der Compiler > tut, ist man auf eine meist unzureichende, ziemlich veraltete (aber > trotzdem überaus längliche) Dokumentation allein der Wirkungen fremden > Codes angewiesen... Warum verzichtest du nicht lieber auf C-Blähcode und musst dich nicht auf fremde Software verlassen (namens Compiler), wenn du das Gleiche mit einem Macroassembler machen kannst? Erkennst du die Analogie?
Marc Vesely schrieb: > Oder in irgendeinem Forum Arduino benutzer anspucken, auch wenn diese > genau dasselbe machen wie du... Ich käme im Leben nicht auf die Idee.
Marc V. schrieb: > Liest doch mal ein bisschen über C++ - da sind so viele Situationen > undefiniert, da kriegt man einen Lachkrampf schon bei oberflächlichem > durchlesen. Was soll da konkret "undefiniert" sein, was in C nicht "undefiniert" ist? Der Lachkrampf gibt sich eventuell von selbst wenn man sich weniger oberflächlich mit dem Thema beschäftigt, eventuell geht einem dann auch ein Licht auf.
Simon schrieb: > Heute behauptete ein Bekannter von mir das man Mikrocontroller besser > mit C++ programmieren kann als in C. > Auf meine Frage warum das so sei, sagte er das man in C++ quasi mehr und > präzisere Werkzeuge habe als mit reinem C. Ich denke, mit keiner anderen Sprache kann man Typsicherheit zur Compilezeit so gut sicher stellen wie mit C++. Dadurch sind prinzipiell schnellere, zuverlässige und kleinere Programme möglich als mit C (egal auf welcher Plattform). > Da ich bisher nur in C programmiert habe und mich mit C++ nicht gut > auskenne, würde ich gerne ein Paar Meinungen dazu hören. Das "Problem" bei C++ sind die Freiheitsgrade. Der Programmierer kann machen was er will. Zudem ist die Sprache komplex (zusammen mit der STL), die sich mit mit C++11 quasi verdoppelt hat. Wenn man sich nicht bewußt ist, was man da macht, werden C++ Programme schnell zu langsamen und unwartbaren Monstren. Wenn du aus der C-Welt kommst und mit dem Gedanken spielst, einen C++ Compiler zu verwenden, dann überlege dir was dich in C meisten stört, und gucke ob es etwas besseres in C++ gibt. -- Auf Anhieb würden mir Namespaces einfallen. Smart Pointer sind die Antwort auf Memory Leaks. Statische Klassen sind "hübscher", als einen Set von Funktionsaufrufen um eine struct zu basteln... also weiterhin "C" mit ein paar kleinen Verbesserungen. Und dann Stück für Stück. :-)
Wilhelm M. schrieb: > Mmh, sowohl C als auch RISC als Architekturmerkmal stammen aus > Elfenbeintürmen ... Wo kommen denn diese Ansichten her? C ist definitiv nicht in einem Elfenbeinturm entstanden, ganz im Gegenteil ist das von einem formalen Standpunkt aus recht grausame Sprache, die viele Grausamkeiten wie undefiniertes Verhalten zulässt. Eine Elfenbeinturm-Sprache ist z.b. Haskell, aber selbst die taugt für "richtigen" Einsatz. RISC ist auch aus sehr konkreten und praktischen Motivationen entstanden, und es ist kein Zufall, dass alle effizienten stromsparenden Prozessorarchitekturen die es heute noch gibt irgendwo einen RISC-artigen Maschinenkode haben.
rmu schrieb: > In C++ lässt sich ohne weiteres Code erstellen, der effizienter als > äquivalenter C-Code läuft, dabei kürzer und weniger fehleranfällig ist. Beispiele für effizienter? [BTW: Ich denke, um nicht Äpfel und Birnen zu vergleichen, muss bei C im Hinterkopf Misra und PC-Lint mitschwingen. Nicht, dass man Misra einhält, sondern dass man die Forderungen nachvollziehen kann und das PC-Lint noch mehr prüft. Zudem halte ich persönlich z.B. Namespaces und Polymorphie für einen Scheinvorteil. Darum akzeptiere ich zwar, wenn jemand kürzer und robuster schreibt, teile das aber bei großen Projekten (>> 1E5 Loc nicht unbedingt)]
Die Anwendung immer komplexerer abstrakter Sprachen ist eine Medaille mit zwei Seiten: Was sich mit sinnvoller Verknüpfung zahlloser Features hinterher an Zeit sparen ließe mußte vorab erstmal zur Beherrschung der Sprache investiert werden: Mikro 7. schrieb: > Zudem ist die Sprache komplex (zusammen mit der > STL), die sich mit mit C++11 quasi verdoppelt hat. Wenn man sich nicht > bewußt ist, was man da macht, werden C++ Programme schnell zu langsamen > und unwartbaren Monstren. Entsprechend dem ungleichen Verhältnis von fähigen zu durchschnittlichen Programmierern dürfte die Softwarequalität in der Praxis ausfallen. > Smart Pointer sind die Antwort auf Memory Leaks. Manchmal löst eine Sprache nur Probleme, die man ohne sie nicht hätte :)
Mikro 7. schrieb: > Smart Pointer sind die Antwort auf Memory Leaks. Habe ich embedded nie, weil ich alleine schon wegen Speicherfragmentierung sowieso keine dynamische Allozierung nutze. Wo nichts alloziert wird, kann auch keine Deallozierung vergessen werden.
Wilhelm M. schrieb: > Mit C++ kann man ein Niveau erreichen, was fast an plattform-Neutralität > grenzt. Dazu muß man eine vernünftige Schichten-Architektur haben, aber das hat mit der Programmiersprache nichts zu tun, und dafür brauche ich auch kein OOP. So als Beispiel.. unter Linux auf x86 entwickelt, Zielplattform Mikrocontroller ohne Betriebssystem. In C.
rmu schrieb: > Was soll da konkret "undefiniert" sein, was in C nicht "undefiniert" > ist? Bei der Vererbung habe ich aufgehört weiterzulesen... > Der Lachkrampf gibt sich eventuell von selbst wenn man sich weniger > oberflächlich mit dem Thema beschäftigt, eventuell geht einem dann auch > ein Licht auf. Von Licht oder Dunkelheit mal abgesehen - das, was man bei uC von C++ gebrauchen kann, hat der C auch. Und plain C wird auch ständig verbessert, da steht die Behauptung mit der Codegrösse auch nicht. Und was mir der Compiler wegoptimiert oder wie der eine bestimmte Aufgabe ausführt, ob zuerst A oder B ausgeführt wird, will ich aber genau vorgeben und nicht dem Compiler überlassen. C als Sprache ist schon furchtbar genug, aber eine Sprache die auf C aufbaut und noch komplizierter ist - nein, nicht für mich und bestimmt nicht für uC... Obwohl, ich beschäftige mich meist mit Industriesteuerungen, da wird in Echtzeit gearbeitet und jede us zählt und kann schon zuviel sein. Es hat mich (vor etwa 7 Jahren) etwa 2 Wochen Zeit gekostet, um einen Programm zu schreiben wo ich einfach mit Häckchen alles auswählen kann - von uC und Timern bis zum Interrupts und Peripherie (mit zugehörigen Bibliotheken gleich eingebunden, natürlich). Das Gerüst für einen Programm ist damit in weniger als 1 Minute fertig. Die Daten werden aus XML für entsprechenden Prozessor ausgelesen - ich brauche mich um neue Typen und neue Bezeichnungen nicht zu kümmern. Wer auch nur einmal stundenlang zwischen Programm und DaBla geschielt hat, weiss wovon ich rede. Welche Vorteile hat der C++ gegenüber C in dieser Beziehung bei uC ? Wie gesagt, für Windows mit mehr als 4GHz, Unmengen von RAM und keiner Notwendigkeit auf irgendetwas in Echtzeit zu reagieren, mag das sicher gehen, aber bei uC bestimmt nicht. P.S. Kann mich nicht mehr genau erinnern wer das gesagt hat, aber in etwa: Mit C kann man sich ganz leicht ins Bein schiessen, mit C++ ist das nicht so einfach aber wenn es passiert, ist gleich das ganze Bein weggeschossen... P.P.S. Wenn der TO dieses in PC-Programmierung gepostet hätte, wurde ich mich gar nicht melden - da ist es witzlos, die offensichtlichen Vorteile von C++ zu bestreiten.
Vincent Samos schrieb: > Die Anwendung immer komplexerer abstrakter Sprachen ist eine Medaille > mit zwei Seiten: Was sich mit sinnvoller Verknüpfung zahlloser Features > hinterher an Zeit sparen ließe mußte vorab erstmal zur Beherrschung der > Sprache investiert werden: Ist das eine Tautologie? Sicherlich sollte man immer (!) Aufwand und Nutzen im professionellen Umfeld abschätzen. > Mikro 7. schrieb: > ... > Entsprechend dem ungleichen Verhältnis von fähigen zu durchschnittlichen > Programmierern dürfte die Softwarequalität in der Praxis ausfallen. Da bin ich neugierig: Wie ist denn das Verhältnis von fähigen zu durchschnittlichen Programmierern? Belastbare Quelle? ;-) >> Smart Pointer sind die Antwort auf Memory Leaks. > > Manchmal löst eine Sprache nur Probleme, die man ohne sie nicht hätte :) Eine der schönen Sachen an C/++ ist, dass man machen kann was man will. Sogar performanten Code, wie in keiner anderen Hochsprache. Allerdings gibt es auch Fallstricke. Macht das C/++ jetzt gut oder böse?! /Rhetorik off
Mikro 7. schrieb: > Vincent Samos schrieb: > Die Anwendung immer komplexerer abstrakter Sprachen ist eine Medaille > mit zwei Seiten: Was sich mit sinnvoller Verknüpfung zahlloser Features > hinterher an Zeit sparen ließe mußte vorab erstmal zur Beherrschung der > Sprache investiert werden: > > Ist das eine Tautologie? Nein. Das bedeutet, daß die Verwendung von C++ gegenüber einfacheren Sprachen nicht per se Zeit sparen muß. > Da bin ich neugierig: Wie ist denn das Verhältnis von fähigen zu > durchschnittlichen Programmierern? Belastbare Quelle? ;-) C++ fordert für gleiche oder bessere Ergebnisse mehr Knowhow. Das haben erfahrungsgemäß wenigere :) > Eine der schönen Sachen an C/++ ist, dass man machen kann was man will. Das sollte eigentlich jede Sprache gewährleisten. > Sogar performanten Code, wie in keiner anderen Hochsprache. Dazu hätte ich gern nähere Infos... > Allerdings > gibt es auch Fallstricke. Macht das C/++ jetzt gut oder böse?! Nein. Komplizierter.
Artur S. schrieb: > Artur S. schrieb: >> Sebastian V. schrieb: >>> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde >>> ich C++ jederzeit vorziehen. >> >> Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren >> Seite. > > Mit meiner Bemerkung ging es mir um "würde ich C++ jederzeit vorziehen". > Das kann man sich so absolut behauptet erst mit einem gut ausgestatteten > Controller erlauben. Nö, das geht auch auf einem Tiny13 ganz prima. Und den willst Du doch wohl sicher nicht als "gut ausgestattet" bezeichnen, oder?
Findelkind schrieb: > Torsten R. schrieb: >> Es gibt Unmengen von features in C++, die > > alle zu erlernen und richtig anzuwenden sind! > Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik > aus dem Elfenbeinturm. C++ kann nichts dafür, daß es Dich überfordert.
Marc V. schrieb: > Natürlich erzeugt der C++ wahrscheinlich > effizienteren Code als der Programierer - nur gilt das eben nur für > diese unnützen Funktionen und Features, die kein normaler Mensch jemals > bei einem 8-bit AVR oder PIC brauchen wird- Weißt Du, es geht gar nicht darum, ob man C++ braucht. Es geht darum, ob es einem die Arbeit leichter macht -- und das tut es, sogar ziemlich gut.
Sheeva P. schrieb: > Nö, das geht auch auf einem Tiny13 ganz prima. Mit solchen leeren Behauptungen tät ich mich auch nur tiefnachts aus der Deckung trauen :)
Max schrieb: > Sheeva P. schrieb: >> Nö, das geht auch auf einem Tiny13 ganz prima. > > Mit solchen leeren Behauptungen tät ich mich auch nur tiefnachts aus der > Deckung trauen :) Keine Sorge, das mach' ich auch tagsüber. Schließlich weiß ich, daß meine Aussage vor allem eines nicht ist: nämlich "leer". ;-)
Hallo Achim, Achim S. schrieb: > Beispiele für effizienter? ein gerne zitiertes Beispiel ist qsort() vs. std::sort(). qsort() nimmt das Sortierkriterium immer als function pointer, und der Aufruf des Sortierkriteriums ist von daher schlechter durch inlining zu entfernen. std::sort() ist ein template und kennt daher den exakten Typen des Sortierkriteriums und wenn der dann eben kein function pointer ist, dann hängt das Sortierkriteriums ganz fest am Typen und der compiler kann das Sortierkriteriums inlinen. In einer Library eines Chip-Herstellers habe ich letzte Woche eine Funktion gesehen, die aus einer gegebenen Eingangs- und Ausgangsfrequenz 3 Parameter für eine PLL ermittelt. Die Implementierung ist eine 3-fach geschachtelte Schleife, die über alle Bereiche jedes Parameters iteriert und guckt ob eine Kombination passt. Diese Funktion wird üblicherweise exakt einmal mit immer den gleichen Parametern aufgerufen und liefert auch immer das selbe Ergebnis. In C++ kannst Du diese Funktion zur Compile-zeit ausführen lassen und im Code liegen dann nur die ermittelten Parameter der PLL. mfg Torsten
Sheeva P. schrieb: > C++ kann nichts dafür, daß es Dich überfordert. Niemand versteht C++ (vollständig), dazu ist es, STL und Boost eingerechnet, viel zu umfangreich. Nichtmal Stroustrup. Das Gefährliche sind dann C++-Programmierer, die die zahlreichen Features zwar anwenden können und deswegen irrtümlich glauben, sie hätten das verstanden, aber nicht im Detail wissen, was hinter der Compilermagic wirklich vor sich geht. Die sind der Grund für Torvalds legendären Rant bezüglich Git und C, daß allein schon C++-Programmierer fernzuhalten ein Grund für C sei. Damit waren nicht die Könner gemeint, sondern die viel zahlreicheren Legoprogrammierer.
Torsten R. schrieb: > Die Implementierung ist eine 3-fach > geschachtelte Schleife, die über alle Bereiche jedes Parameters iteriert > und guckt ob eine Kombination passt. Daß C einen hirnlosen Algorithmus nicht in Konstanten umzuwandeln kann, ist kein Argument für C++, sondern gegen den hirnlosen Algorithmus. Echt mal, eine dreifach verschachtelte Schleife mit Rumprobieren aller Möglichkeiten ist doch die bedingungslose Kapitulation des Programmierers vor dem Problem.
Nop schrieb: > Echt mal, eine dreifach verschachtelte Schleife mit Rumprobieren aller > Möglichkeiten ist doch die bedingungslose Kapitulation des > Programmierers vor dem Problem. Würde mal sagen nicht Zwangsweise. Wenn du drei Unbekannte aus 2 gegebenen Werten berechnen musst, kannst du dich auf den Kopf stellen. Du wirst kaum einen Alorithmus jenseits von BruteForce finden, der das berechnet. Ich denke mal die Alternativen zu den drei Schleifen sind deutlich aufwendiger und damit Fehleranfälliger und schwerer zu verstehen. Außerdem, wenn der Compiler das eh ausrechnet, ist der nutzen dem Aufwand gegenüber doch angemessen.
Nop schrieb: > Echt mal, eine dreifach verschachtelte Schleife mit Rumprobieren aller > Möglichkeiten ist doch die bedingungslose Kapitulation des > Programmierers vor dem Problem. Das ist nicht der Punkt. Selbst wenn Du einen "besseren" Algorithmus findest, wird der im Bezug auf Speicherverbrauch und Laufzeit deutlich schlechter sein, als das Laden des PLL-Konfigurationsregister mit einer Konstanten.
Meine Güte, und sie sind nicht totzukriegen. Mal wieder die Klassiker bringen: 1) Wer guten Code schreiben will, muss verstehen, was hinten rausfällt, spätestens, wenn er's debuggen muss 2) Wer somit gut C++ schreiben will, muss C vollständig beherrschen/verstehen. Spätestens an dem Punkt entscheidet sich: a) Wohlfühl-Programmierer b) Ergebnisorientierter Programmierer Letzterer kriegt typischerweise in der Industrie den Auftrag. Auch für einen uC gilt das Konzept eines robusten/kompakten Kernels (oder gerade da...) Das kann man schon in C++ schreiben (wollen). Nur: - new ist verboten (malloc aber auch) - Exceptions sind verboten (stack unwinding auf uC...) - STL nur noch bedingt zu geniessen - und die Liste lässt sich beliebig fortsetzen Da bleibt dann von den C++-Schmankerl nicht mehr so viel übrig, im Gegenteil, es verkompliziert. Das sind ein paar Gründe, warum alle namhaften Kernel nach wie vor in C geschrieben sind. Auch wenn Herr Torvalds nicht immer Recht hat: Hier hat er's :-)
Achim S. schrieb: >> In C++ lässt sich ohne weiteres Code erstellen, der effizienter als >> äquivalenter C-Code läuft, dabei kürzer und weniger fehleranfällig ist. > > Beispiele für effizienter? Als Beispiel für Code der in C++ effizienter realsierbar wäre führe ich die STM HAL-Libs an, da nimmt man ja an, dass das von Profis die ihr Geschäft verstehen gemacht wurden. Wenn man äquivalenten Code mit modernen C++ Techniken implementiert kommt in Summe ein kleineres Programm (Codesize) heraus, vor allem deswegen, weil der C++-Compiler viele der Laufzeit-Checks auf NULL etc. schon zur Compile-Zeit analysieren und daher (weg-)optimieren kann, genauso ist es grad bei ARM oft sinnvoll, kurze Funktionen inline einzubinden. Ein Funktionsaufruf kostet auch Platz. Das Ausfüllen und Herumschicken dieser riesigen Initialisier-Structs etc. würde man sich auch grossteils sparen. Makros zur Definition von Registern und Hardware würde man durch passende Templates und dazupassende Traits ersetzen, dann kommts nicht mehr vor, dass man in ein RO-Register reinschreibt, weil sich der Code gar nicht übersetzen lässt. Wenn man sich auf Exceptions einlässt kann man die Fehlerbehandlung dort machen wo sie Sinn macht, und kann sich das stoische Abfragen von Rückgabewerten auf Fehlerwerte sparen. Kann sich auszahlen, muss aber nicht. In C könnte man ähnliches mit setjmp/longjmp erreichen, hätte aber mehr overhead und gleichzeitig würde alles recht unübersichtlich und Fehleranfällig. Exceptions haben mit GCC-ARM keinen Laufzeit-Overhead, d.h. der Code "zwischen" der Stelle wo geworfen und dort wo gefangen wird ist nicht irgendwie speziell oder am Exception-Mechanismus irgendwie beteiligt. C++ Mechanismen garantieren, dass Destruktoren lokaler Objekte ausgeführt werden, egal wie man den Kontext verlässt, was extrem praktisch für Locks oder Interrupt-Sperren ist, da kann man einfach nicht vergessen, etwas wieder freizugeben. etc...
Strubi schrieb: > 2) Wer somit gut C++ schreiben will, muss C vollständig > beherrschen/verstehen. Wozu? Das musst du mal näher ausführen. Wenn ich in C++ programmieren möchte, muss ich erst mall C++ verstehen. Was soll mir eine andere Programmiersprache bringen. Im gegenteil, die meisten "Umsteiger" tun sich schwer damit, C außen vor zu lassen und dann kommt ein furchtbarer Mischmasch raus. Strubi schrieb: > - new ist verboten (malloc aber auch) > - Exceptions sind verboten (stack unwinding auf uC...) > - STL nur noch bedingt zu geniessen > - und die Liste lässt sich beliebig fortsetzen Auf jeden Fall bleiben Typsicherheit, Templates und Funktionsoverloading über. Das reicht mir schon um C++ vorzuziehen.
Marc V. schrieb: > P.S. > Kann mich nicht mehr genau erinnern wer das gesagt hat, aber in etwa: > Mit C kann man sich ganz leicht ins Bein schiessen, mit C++ ist das > nicht so einfach aber wenn es passiert, ist gleich das ganze Bein > weggeschossen... Mir sind auch schon einige Steuerungen untergekommen, meistens deswegen, weil nach einem Compilerwechsel (C) nichts mehr ging. Meistens hat sich herausgestellt, dass sich irgendwo eine Routine auf eine bestimmte Variante eines undefinierten C-Konstrukts verhalten hat, die beim neueren Compiler halt je nach Optimierungsflags sich anders verhält. (Das Ergebnis einer undefinierten Aktion darf in C von allem und nichts oder auch von der Mondphase abhängen). Das betraf auch immer Codestellen, die man in C++ komplett anders realisiert hätte. ("Generische" Datenstrukturen, Filter, ...)
Strubi schrieb: > Nur: > - new ist verboten (malloc aber auch) new impliziert nicht dass Speicher dynamisch verwaltet wird. placement new. > - Exceptions sind verboten (stack unwinding auf uC...) geht auf ARM Cortex M0 vorzüglich > - STL nur noch bedingt zu geniessen Die iostreams muss man sich sparen, der Rest ist schon brauchbar. Manches könnte zwar besser gelöst sein (Allocatoren), aber std::arrays sind um einiges angenehmer als nackte Pointer. > - und die Liste lässt sich beliebig fortsetzen alles überholte Vorstellungen > Da bleibt dann von den C++-Schmankerl nicht mehr so viel übrig, im > Gegenteil, es verkompliziert. > Das sind ein paar Gründe, warum alle namhaften Kernel nach wie vor in C > geschrieben sind. Auch wenn Herr Torvalds nicht immer Recht hat: Hier > hat er's :-) Das ist historisch bedingt. 1-2 Kernel-Versionen waren mit g++ zu kompilieren, der Versuch wurde aber wieder aufgegeben, weil der Compiler damals (in den 90ern) zu buggy war. Windows NT Kern und Abkömmlinge sind auch großteils in C++ geschrieben AFAIK, und das fällt auch unter "namhafter Kern" selbst wenn man kein Windows-Fan ist. Der Linux Kernel ist auch vom Organisatorischen her vermutlich nicht für C++ geeignet, da man konstant herumstreiten würde/müsste, welches Subset von C++ verwendet werden kann/darf. Typische µC-Projekte sind um Größenordnungen überschaubarer als der Linux-Kern.
Sebastian V. schrieb: > Da C++ bis auf wenige Ausnahmen auch alle Features von C enhält und dazu > noch einen Haufen neuer Features, ist C++ deutlich mächtiger (und > komplizierter). Wenn man weiß wie man mit den neuen Features umgeht und > welche davon auch für Mikrocontroller geeignet sind dann sehe ich in der > Verwendung von C++ auf Mikrocontrollern eigentlich nur Vorteile. Wobei > jetzt auch wieder einige Leute behaupten werden, dass nur das "erste" C > nach K&R (oder Assembler) das einzig Wahre ist. Endlich mal jemand mit Ahnung! @TO: Nimm dir das genau so zu Herzen!
Und es gibt ein paar ganz einfache Dinge in C++, die einem das Leben auf der untersten Ebene leichter machen. Dazu zähle ich auch: - user-defined-literals, etwa 1_ms oder 43_us oder 42_MHz und die Operatoren dafür - binary-literals, etwa 0b01000101 - Dezimaltrenner: etwa uint32_t x = 1'000'000; - uniform-initialization (ohne narrowing) - std::array, std::optional (man braucht keine STL dafür, das hat man sich ganz schnell selbst gemacht!) Das macht das Schreiben angenehmer ... und die Laufzeit leidet nicht.
:
Bearbeitet durch User
Torsten R. schrieb: > Das ist nicht der Punkt. Selbst wenn Du einen "besseren" Algorithmus > findest, wird der im Bezug auf Speicherverbrauch und Laufzeit deutlich > schlechter sein, als das Laden des PLL-Konfigurationsregister mit einer > Konstanten. Nö. In C nehme ich dafür Brain 1.0, lese das Handbuch, definiere einen gültigen Satz an Parametern und gut. Hatte ich neulich für ein Projekt mit fünf einstellbaren Taktfrequenzen und ich glaub 5 PLL-Parametern pro Frequenz, dazu natürlich noch voltage scaling, Flash-Waitstates und Caches an/aus. Dann nimmt man eine Funktion, der man diese ganzen Parameter übergibt (wo der ganze Registerkrams dann gemacht wird), und eine andere, die man als API aufruft, mit nem Enum der gewünschten Systemfrequenz. Die ist dann im Wesentlichen ein Switch-Case, dessen Zweck es ist, Code-Duplikation der eigentliche Einstellfunktion zu vermeiden. Andererseits ist der Vorteil an diesem Schleifen-Ansatz mit C++ natürlich schon nicht zu leugnen: - man braucht kein Hirn benutzen (darf man nicht unterschätzen). - der Compiler entfernt den hirnlosen Bloat, so daß der Kunde nicht merkt, daß man nicht denkt. - und das Beste zum Schluß: Wenn man diesen Ansatz konsequent befolgt, kann man leicht Compilierzeiten im Stundenbereich erzeugen. Profis dosieren das allerdings gerade soweit, daß ein Compile-Run genug aufgebläht wird für ein, zwei Postings bei µC.net, aber nicht soweit, daß man noch andere sinnvolle Sachen dazwischen tun könnte. So, ich könnt dazu noch mehr schreiben, aber der Compiler ist gerade fertig.
Nop schrieb: > Nö. In C nehme ich dafür Brain 1.0, lese das Handbuch, Genau, und weil Brain 1.0 ja bekanntlich keinerlei Bugs und Seiteneffekte aufweist, versucht man in der Praxis gewöhnlich diesen Faktor so weit wie nur irgend Möglich zu begrenzen.
Ach ja, in C geht das natürlich auch, braucht man nur ein geeignetes Buildscript. Man nimmt sich dazu einfach ein Headerfile, wo die gewünschten Zielwerte drinstehen, welche man im Buildscript (vor dem Compiler-Run) mit einem Perlscript ausliest. Die Berechnungen macht man dann in Perl, und fügt die Ergebnisse denn autogeneriert aus dem Script heraus dem Headerfile hinzu. Danach erst wird der Compiler aufgerufen. Das hat den Vorteil, daß man dabei nicht auf langweilige Sachen wie relativ simple Schleifeniterationen begrenzt ist, sondern man kann dieses Verfahren auch z.B. zum Invertieren von größeren Matrizen benutzen, oder für numerische Integration, das näherungsweise Lösen von Differentialgleichungen oder ähnliche Späße. Trotzdem wird der C-Code nicht aufgebläht. Genial, oder? Außerdem muß man dann als C-Programmierer nicht mehr neidisch auf die Build-Zeiten der C++-Kollegen schielen.
Nop schrieb: > Ach ja, in C geht das natürlich auch, braucht man nur ein > geeignetes > Buildscript. > > Man nimmt sich dazu einfach ein Headerfile, wo die gewünschten Zielwerte > drinstehen, welche man im Buildscript (vor dem Compiler-Run) mit einem > Perlscript ausliest. Die Berechnungen macht man dann in Perl, und fügt > die Ergebnisse denn autogeneriert aus dem Script heraus dem Headerfile > hinzu. Danach erst wird der Compiler aufgerufen. > > Das hat den Vorteil, daß man dabei nicht auf langweilige Sachen wie > relativ simple Schleifeniterationen begrenzt ist, sondern man kann > dieses Verfahren auch z.B. zum Invertieren von größeren Matrizen > benutzen, oder für numerische Integration, das näherungsweise Lösen von > Differentialgleichungen oder ähnliche Späße. Trotzdem wird der C-Code > nicht aufgebläht. Genial, oder? > > Außerdem muß man dann als C-Programmierer nicht mehr neidisch auf die > Build-Zeiten der C++-Kollegen schielen. Troll? du willst also eine andere Programmiersprachen nutzen, um deine Werte auszurechen und willst das auch noch als Feature verkaufen? Wenn du denktst, dass der Compiler nur einfache Schleifen optimieren kanns, liegst du falsch.
Ein wichtiges Thema ist auch, dass es für µC von den Herstellern (afaik) keine C++-Bibliotheken gibt. Sich mit C++ an die C-Libs anzukoppeln ist bezüglich des Programmierstils immer ein bisschen zwittrig, aber dennoch möglich. Für Tipps für brauchbare HALs in C++ wäre ich dankbar :)
:
Bearbeitet durch User
nicht"Gast" schrieb: > Troll? Naja komm, wer hat denn angefangen mit einer verschachtelten Rumprobierschleife?! Und das dann auch noch als Feature zu verkaufen, daß der Compiler so einen Unsinn covern kann. Die Buildzeiten werden bei einem größeren Projekt dann dementsprechend ausfallen, und somit auch die Turnaroundzeiten. Die sind bei compilierten Sprachen ohnehin schon deutlich größer als bei Scriptsprachen, da muß man den Buildprozeß nicht auch noch künstlich aufblähen. Aber wenn man schon auf einen aufgeblähten Buildprozeß steht, dann kann man auch gleich mit Scripten rumsauen. Ganz im Sinne von "don't re-invent the wheel" wären dann z.B. Matlabscripte für Numerikkrams eine "gute" Idee.
Nop schrieb: > Naja komm, wer hat denn angefangen mit einer verschachtelten > Rumprobierschleife?! Und das dann auch noch als Feature zu verkaufen, > daß der Compiler so einen Unsinn covern kann. Die Buildzeiten werden bei > einem größeren Projekt dann dementsprechend ausfallen, und somit auch > die Turnaroundzeiten. Üblich ist, dass nur die sourcen neu übersetzt werden, die sich geändert haben. Und seinen Quarz ändert man üblicherweise nicht laufend. Die Compile-Zeiten für einen kompletten rebuild spielen eine untergeordnete Rolle. Und wie kommst Du darauf, dass ein Perl-Interpreter schneller gestartet ist und den Algorithmus ausgeführt hat, als ein C++ compiler, der eh schon läuft?
> Üblich ist, dass nur die sourcen neu übersetzt werden, die sich geändert > haben. Und seinen Quarz ändert man üblicherweise nicht laufend. Üblich ist es, daß man mal ins Datenblatt guckt und schlichtweg einen Satz von PLL-Werten einmal hernimmt, so wie oben geschildert. Zumal man das dann ohnehin noch kapselt, wenn man zur Laufzeit verschiedene Taktungen braucht, und dann ist es auch nicht mit der PLL getan, sondern Waitstates und voltage scaling kommen auch noch hinzu. Kann man ja ne fünffach verschachtelte Schleife nehmen. Ach ja, gerne auch sechsfach, auf Cortex-M4 sind es ja schon vier PLL-Parameter. > Compile-Zeiten für einen kompletten rebuild spielen eine untergeordnete > Rolle. Die Einstellung dahinter schon, denn genau derselbe Unsinn wird sich dann auch in anderen Dateien abspielen. > Und wie kommst Du darauf, dass ein Perl-Interpreter schneller > gestartet ist und den Algorithmus ausgeführt hat, als ein C++ compiler, > der eh schon läuft? Wieso schnell? Die Buildzeiten sind Leuten mit so einer Mentalität doch ohnehin völlig egal. Mit einem Script kann man halt noch wesentlich vielseitiger Zeit verschwenden, ohne daß das im Binary bemerkbar wird. Genau das war ja gerade als tolles Feature genannt worden. Wirklich spaßig wird das übrigens, wenn diese Leute mal an ernsthafte Software gesetzt werden. Na das gibt dann aber lange Gesichter, wenn in den Vorschriften steht, daß Compiler-Optimierungen nicht gestattet sind.
Übrigens, egal wie beknackt eine Idee ist, es gibt Leute, die machen das. Insofern ist das dann nicht einmal getrollt. In dem Fall mit Scripten erstmal Quelltext aufbereiten. Bei libopencm3 muß man allen Ernstes Python installiert haben zum Build, weil ein Teil der Quelltexte mit Python-Scripten generiert wird. oO
Um mal zur Ursprungsfrage zurückzukommen: Ja es geht, auch ohne große Einbußen, wenn man auf gewisse features wie SEH oder statische Objekte verzichtet*. Ob es sinnvoll ist, hängt vom Einsatzgebiet ab. Wo sich die Problemstellung gut objektorientiert abbilden läßt (z.B. in komplexeren Zutrittskontrollsystemen, bei denen Dinge wie Türen und Leser programmatisch repräsentiert werden können), kann es enorm helfen. Wo "nur" relativ maschinennah gearbeitet wird (z.B. Messfühlerdatenpumpen), ist es eher optional. C++ kann darüber hinaus helfen, gewisse Standardfehlern in C zu vermeiden. Hier ist ein fast schon triviales beispiel (Pseudocode): class MutexOp { private: osSpecificMutexHandle m_Mutex; public: MutexOp(osSpecificMutexHandle p_Mutex) {m_Mutex = p_Mutex;osSpecificClaimMutex()}; ~MutexOp(void) {osSpecificReleaseMutex()}; } Wer dann also zu schützenden Block in die Deklaration { MutexOp(anExistingMutex); // zu schützender Code } einwickelt, wird nicht in die Falle tappen, einen Funktionsausstieg ohne Abgeben des Mutex zu verbraten (weil C++ garantiert, daß der Konstruktur beim Eintreten in den scope aufgerufen wird und der Destruktor bei jedem Ausstieg aus dem scope). Mit ähnlichen Mitteln lassen sich eine gewisse Klasse von Speicherlecks vermeiden. *Eines der Probleme mit SEH ist, dass es Zusatzsegmente anlegt, die einem das Speicherlayout verbiegen. Das Problem mit statisch angelegten Objekten ist, dass der Konstruktur vom Laufzeitcode sehr früh aufgerufen wird, was bei Embedded Systemen heisst, dass das System mglw. noch nicht vollständig initialisert ist. Wir haben bei einem Kunden ein mäßig komplexes System unter C++ mit verschiedenen Middlewaresuiten seit vielen jahren im Einsatz, und ich kann mit Sicherheit sagen, daß die Einkapslungsmechanismen eine Menge Fehler vermieden haben, die unter C sicherlich aufgetreten wären.
Nop schrieb: > Sheeva P. schrieb: >> C++ kann nichts dafür, daß es Dich überfordert. > > Niemand versteht C++ (vollständig), dazu ist es, STL und Boost > eingerechnet, viel zu umfangreich. Nichtmal Stroustrup. Quatsch. C++ und die STL sind zwar zweifellos umfangreicher als C, aber bei Weitem nicht so riesig, daß man sie nicht verstehen kann. Andere Entwickler bekommen das ja auch hin. Was Boost angeht, ist das eine Sammlung von Bibliotheken und Frameworks, die kein Entwickler komplett beherrschen muß. Man sucht sich heraus, was man braucht, und benutzt es, genauso wie bei allen anderen Bibliotheken aus Drittquellen. Der einzige Unterschied ist, daß die Boost-Libs in einer Sammlung vorliegen und nicht von diversen Drittanbietern zusammengesucht werden müssen.
Strubi schrieb: > Auch für einen uC gilt das Konzept eines robusten/kompakten Kernels > (oder gerade da...) > Das kann man schon in C++ schreiben (wollen). > > Nur: > - new ist verboten (malloc aber auch) > - Exceptions sind verboten (stack unwinding auf uC...) > - STL nur noch bedingt zu geniessen > - und die Liste lässt sich beliebig fortsetzen Nein, läßt sie sich nicht, eigentlich fehlt nur dynamisches Dispatching. > Da bleibt dann von den C++-Schmankerl nicht mehr so viel übrig, im > Gegenteil, es verkompliziert. Ach Gottchen, Du suchst Dir ein paar wenige Features von C++ heraus und behauptest dann einfach mal, ohne diese Features sei C++ nutzlos und würde die Sache verkomplizieren. Aber Datenkapselung, Polymorphie, Vererbung und Templates funktionieren auch auf kleinen uCs wunderbar und machen viele Dinge wesentlich einfacher, sicherer und robuster.
Aargh. Das schlimmste an diesen immer wieder aufkeimenden C++-auf-uC-Bullshit-Bingos ist jeweils, dass sich ohne Ende Frickler zu Wort melden, die im Prinzip für ihr kleines eigenes Wohlfühl-HAL-Framework Recht haben mögen, aber oft die Realität in den Kollaborativen verkennen - oder, dass eine Deadline, Robustheitskriterien und Kostenrahmen einzuhalten sind und es nicht erwünscht ist, sich zu verzetteln. Dazu kommen Aspekte der Portabilität, Wartbarkeit und Standardisierung, die bei C++ einfach "a fucking mess" ist. Das spart nach meiner Statistik keine Zeit, im Gegenteil. Ich habe absolut nichts gegen C++ (au contraire, ich nutze es ausgiebig) - sofern ein vernünftiges Framework vorliegt und man von gewissen Features absieht, die einfach in manchen Kontexten "broken by design" sind (wie z.B. exceptions in einem RT-Kernel). Ergo gilt Linus' rant betr. Kernel heute noch, das hat nichts mit Compiler bugs zu tun. Die Relität sieht so aus, dass die meisten Programmierer oft nicht wissen, was sie da eigentlich tun und mit grossen Augen ihr Standardsätzchen abspulen, wenn sie den resultierenden Assemblercode zu Gesicht bekommen: Assembler macht doch heute keiner mehr. Spätestens dann ist ein netter Hinweis auf die crt0.S oder SIMD-Mathlib fällig... Dennoch muss dann der Müll erst mal aufgeräumt werden und dann gehen genau solche Diskussionen wie hier los. Fakt ist, dass man noch immer in C die grösstmögliche (und portable!) Kontrolle über den generierten Code hat und mit geeigneten Tools (Rational Rose, lint, valgrind, etc.) Schwachstellen im Vorfeld effizient genug auffindet. Bei einem robusten Kernel ist diese "Verbosity" gewünscht und gewollt. Spätestens dann, wenn Fehlerszenarien per In-Circuit debuggt werden müssen, oder coverage fällig wird. Da ist es manchmal hilfreich, wenn ein Superset ("++") einer Sprache einfach von vornherein ausgeklammert wird. Und das Beispiel Windows NT hätte man besser nicht als repräsentatives Pro für ein C++-Kernel genannt... (ich sage nur: Scheduler). Auf einer darüberliegenden Schicht, insbesondere in einer geschützten Umgebung, macht C++ Sinn, sofern man eine gewisse Komplexität im OO-Sinne verringern kann. Ich sehe nur keinen Sinn in Einzeilern, die a la Boost eine Menge unnützen Code generieren. Was Kollaborativen in der C++-Domäne angeht, kann man sich immer wunderbar streiten. Als Fan von Bibliothekskonzepten geoutet: die meisten kompakten Libraries, die auch auf einem uC brauchbar sind, sind nun mal in C geschrieben. Das ist aber die klassische Meinung der *nix/Opensource-Affinen, im Firmenumfeld mag eine ganz andere Religion gelten (und auch gerechtfertigt sein).
Also Leute, ich verstehe überhaupt gar nicht, was diese Aufregung soll. Schreibt doch Euren Code in C und übersetzt ihn mit einem C++-Compiler. Und dann sucht Ihr Euch ein paar C++-features raus, die Euch lohnenswert erscheinen. Der eine macht eben nur ganz zaghafte Versuche: vielleicht verwendet er dann das erste mal in seinem Leben ad-hoc-Polymorphie (aka Funktionsüberladung) oder erkennt die wundersame Welt von constexpr gegenüber dem Präprozessor. Oder auch nur user-defined-literals und binary-literals. Der nächste macht sich ggf. auf in Richtung parametrische Polymorphy (aka templates). Es geht doch alles unter einem Dach. Es ist doch keine Entscheidung von C oder C++, sondern eigentlich nur, welche der Sprachmerkmale ich schon verstehe, als sinnvoll erachte und dann auch nutzen möchte. Jedenfalls würde ich mir ein Forum wünschen, wo man über echte Designaspekte diskutieren kann, und nicht die eine Fraktion die andere niedermacht, weil man sich unverstanden fühlt oder glaubt, alles besser zu wissen.
Wilhelm M. schrieb: > Also Leute, ich verstehe überhaupt gar nicht, was diese Aufregung soll. > Schreibt doch Euren Code in C und übersetzt ihn mit einem C++-Compiler. Aber Wilhelm, das geht doch nicht. Sobald man ein großes C oder cpp (*) als Source-File-Extension eintippt, explodiert der Rechner wegen Code-Bloat. zudem versteht man dann auch schlagartig den selbst geschriebenen Code nicht mehr. Alles viel zu gefährlich. ;-)) *je nach OS. Ogott, nächste Falle ...
einfach mal bei Google CppCon 2016 eingeben für alle die, die des Englischen mächtig sind. meine 2 Lieblingsvideos: https://youtu.be/D7Sd8A6_fYU https://youtu.be/zBkNBP00wJE Besonders der 2. Link ist beeindruckend. Commodore C64 in C++ ohne Overhead programmieren. Das Ergebnis für mich lautet nur, egal ob C oder C++, werde besser mit der Sprache, die du schon kannst. Kannst du noch keine von beiden, wirf ne Münze, eine bessere Begründung für die eine oder andere Sprache gibt es nicht. Gruß, dasrotemopped.
oder man folgt dem Trend, den der C++ Experte festgestellt hat.
Wilhelm M. schrieb: > Jedenfalls würde ich mir ein Forum wünschen, wo > man über echte Designaspekte diskutieren kann, und nicht die eine > Fraktion die andere niedermacht, weil man sich unverstanden fühlt oder > glaubt, alles besser zu wissen. Danke! Du schreibst mir aus der Seele.
dasrotemopped schrieb: > einfach mal bei Google CppCon 2016 eingeben für alle die, die des > Englischen mächtig sind. > > meine 2 Lieblingsvideos: > https://youtu.be/D7Sd8A6_fYU > > https://youtu.be/zBkNBP00wJE > Ja, die habe ich natürlich auch gesehen, wobei Dan am Ende seines talks auf ein paar wichtige nicht-technische Dinge eingeht. Und das betrifft den Umgang mit neuen bzw. anderen Sprachmerkmalen. Die Erkenntnis kommt nur, wenn man einmal das Gefühl gehabt hat, etwas anders machen zu müssen, und man dann auch Hilfe erhalten hat, weil man sich auf Neues eingelassen hat! Aus den gleichen Gründen wie Dan habe ich deswegen in diesem Thread wie auch in den anderen Threads zum Thema erst mal die vermeintlich kleinen Dinge hervorgehoben (s.o.). In den Zusammenhang gehören natürlich auch domänen-spezifische Datentypen und const-correctness. Und mein Lieblingszitat von Scott: "Ein Interface muss leicht richtig und schwer falsch zu benutzen sein"! Dazu gehört auch RAII (s.a. obiges Beispiel mit dem mutex-locker). Herb Sutter sagte mal auf die Frage, was sein liebstes syntaktisches Konstrukt in C++ sei: "}" Zum Experimentieren ist übrigens http://gcc.godbolt.org/ wirklich gut geeignet. Wer dort allerdings den neueren avr-gcc (> 6.2) drin haben möchte, muss sich das lokal aufsetzen. VG
Strubi schrieb: > Aargh. > Das schlimmste an diesen immer wieder aufkeimenden > C++-auf-uC-Bullshit-Bingos ist [viel blabla gelöscht] > im Gegenteil. Dass die Diskussion ausarten wird war mir auch gleich klar. Was sich in der Praxis wie auszahlt oder ausgeht hängt hauptsächlich an den Ausführenden. Wenn man Code für verschiedene Architekturen generisch schreiben will kommt so der so auch mit C ein "ad-hoc-HAL" heraus, einen Standard gibts da ja nicht. > Ich habe absolut nichts gegen C++ (au contraire, ich nutze es ausgiebig) > - sofern ein vernünftiges Framework vorliegt und man von gewissen > Features absieht, die einfach in manchen Kontexten "broken by design" > sind (wie z.B. exceptions in einem RT-Kernel). exceptions sind für Ausnahmen gedacht, die sollten in einem RT-Kernel im realtime-zeitkritiscen Teil per Definition nicht passieren. Ausserhalb sind die unkritisch, aber man muss halt genau im Aug haben was man tut. > Ergo gilt Linus' rant betr. Kernel heute noch, das hat nichts mit > Compiler bugs zu tun. Die Relität sieht so aus, dass die meisten > Programmierer oft nicht wissen, was sie da eigentlich tun und mit > grossen Augen ihr Standardsätzchen abspulen, wenn sie den resultierenden > Assemblercode zu Gesicht bekommen: Assembler macht doch heute keiner > mehr. Wer bei einem µC Projekt NICHT standardmässig das asm-listing erzeugt und regelmässig kontrolliert bzw. auf Codesize anschaut macht eh was falsch. Hat ja nichts mit C oder C++ zu tun. IIRC hat Linus/x nicht vorgehabt spezielle C++ features zu verwenden, man wollte nur die bessere Typprüfung ausnutzen. > Spätestens dann, wenn Fehlerszenarien > per In-Circuit debuggt werden müssen, oder coverage fällig wird. > Da ist es manchmal hilfreich, wenn ein Superset ("++") einer Sprache > einfach von vornherein ausgeklammert wird. geht genauso mit C++, was soll da ein Problem darstellen. Genauso kann man sagen, dass sich viele Problemtypen mit C++ schon statisch vermeiden lassen, die man unter C umständlich dynamisch (zur Laufzeit) debuggen muss. Valgrind und ähnliche Memory-Debugger werden auf µC nicht funktionieren, da fehlt die nötige Hardware (MMU, RAM). Rational Rose würde ich wie einen Nuklear-Störfall behandeln, und am besten gleich mitsamt Hardware in einen Salzstock einlagern. Ich kenn das nur als UML "Tool", und UML macht mit C gleich nochmal halb so wenig Sinn. Eventuell Rational Purify gemeint? Kann man das auf µC verwenden? > Und das Beispiel Windows NT hätte man besser nicht als repräsentatives > Pro für ein C++-Kernel genannt... (ich sage nur: Scheduler). war kein Pro, sondern nur ein Ist. > Auf einer darüberliegenden Schicht, insbesondere in einer geschützten > Umgebung, macht C++ Sinn, sofern man eine gewisse Komplexität im > OO-Sinne verringern kann. Ich sehe nur keinen Sinn in Einzeilern, die a > la Boost eine Menge unnützen Code generieren. > > Was Kollaborativen in der C++-Domäne angeht, kann man sich immer > wunderbar streiten. Als Fan von Bibliothekskonzepten geoutet: die > meisten kompakten Libraries, die auch auf einem uC brauchbar sind, sind > nun mal in C geschrieben. > Das ist aber die klassische Meinung der *nix/Opensource-Affinen, im > Firmenumfeld mag eine ganz andere Religion gelten (und auch > gerechtfertigt sein). Firmenreligion ist oft "VAX-kompatibles K&R C, das haben wir immer schon so gemacht", Revisionskontrolle per kopieren und ummurxen, das ist auf keinen Fall produktiver als C++ mit boost etc... So das wars. Meine Popcorn sind alle. Viel Spass noch.
Moin, rmu schrieb: > exceptions sind für Ausnahmen gedacht, die sollten in einem RT-Kernel im > realtime-zeitkritiscen Teil per Definition nicht passieren. Ausserhalb > sind die unkritisch, aber man muss halt genau im Aug haben was man tut. Das Kritische wird oft erst bei der coverage augenscheinlich, also wenn man für jede Kombination von Ausnahmen (Fehlercodes) eine entsprechendes Handling nachweisen muss. Da gibt's unterschiedliche Philosophien, meine ist, dass Fehler dort behandelt werden, wo sie passieren. Jegliche Propagation von unkontrolliertem Fehler-Handling auf unterschiedliche Funktionslayer ist ein Albtraum. Bequem als schneller Hack, aber im Reg'test fliegt's in der Fehlersimulation durch. Dann gibt es eine Latte weiterer Probleme beim Stack-Unwinding auf Kernel-Level, da ist C++ schlicht "broken by design". Gibt da nen netten Artikel zu: http://www.lighterra.com/papers/exceptionsharmful/ Bei Python und Java sind Exceptions legitim, da das "Kernel" schon eine atomar arbeitende Stack-Maschine bereitstellt. Also: Nicht grundsätzlich sind Exceptions böse. > geht genauso mit C++, was soll da ein Problem darstellen. Genauso kann > man sagen, dass sich viele Problemtypen mit C++ schon statisch vermeiden > lassen, die man unter C umständlich dynamisch (zur Laufzeit) debuggen > muss. Valgrind und ähnliche Memory-Debugger werden auf µC nicht > funktionieren, da fehlt die nötige Hardware (MMU, RAM). > Das stimmt. Aber deinen Code kannst du ja schon mal im Trockentest unter deinem Lieblings-OS durch valgrind jagen bzw. im qemu durchemulieren, bevor du ihn auf den uC portierst. > Rational Rose würde ich wie einen Nuklear-Störfall behandeln, und am > besten gleich mitsamt Hardware in einen Salzstock einlagern. Ich kenn > das nur als UML "Tool", und UML macht mit C gleich nochmal halb so wenig > Sinn. Eventuell Rational Purify gemeint? Kann man das auf µC verwenden? Kann sein dass das Purify war, aber Regressionstests wurden mit Rose entwickelt, wenn ich mich nicht täusche. Konnte für unsern Zweck aber schliesslich auch nicht mehr als Python und gcov, zumindest vor ca. 15 Jahren. Mit dem obigen "Trockentest"-Ansatz zur Code-Verifikation kann man's sicher auch für nen uC anwenden, aber das wäre für mich auch eine Art der Verzettelung.. > Firmenreligion ist oft "VAX-kompatibles K&R C, das haben wir immer schon > so gemacht", Revisionskontrolle per kopieren und ummurxen, das ist auf > keinen Fall produktiver als C++ mit boost etc... Für sowas gibts ja git, was ja auch in C geschrieben ist. Der Rest erledigt sich heutzutage ja per SCRUM. Sorry für den Scherz. So einige Firmen dürften nach Experimenten mit wunderschönen akademischen Ansätzen wieder zu den Klassikern zurückgekehrt sein, weil ebendiese Ansätze eine Menge Geld gekostet haben, spätestens als das Zeug im Feld jemandem um die Ohren flog - soweit meine bescheidene Meinung als SW-Feuerlöscher.
Passend zum Titel dieses Threads gibt es auf www.heise.de gerade den Artikel "Schlanke Embeded-Entwicklung mit Small C++" https://www.heise.de/developer/artikel/Schlanke-Embeded-Entwicklung-mit-Small-C-3576516.html
Leider hat der Author nicht bedacht, dass
1 | constexpr uint8_t volatile *portReg() { |
2 | return reinterpret_cast<uint8_t volatile *>(port); |
3 | }
|
niemals als constexpr ausgewertet werden kann / darf, da dort ein reinterpret_cast enthalten ist Man kann also etwa
1 | constexpr auto x = p.portReg(); |
nicht schreiben (wenn man mal testweise portReg() public macht).
Strubi schrieb: > Da gibt's unterschiedliche Philosophien, meine > ist, dass Fehler dort behandelt werden, wo sie passieren. Jegliche > Propagation von unkontrolliertem Fehler-Handling auf unterschiedliche > Funktionslayer ist ein Albtraum. Das ist ja interessant. Warum ist da bloß früher keiner drauf gekommen? Irgendwas mit dem ich kommunizieren will antwortet nicht oder schickt Müll? Kein Problem! Dann werden einfach irgendwelche Antworten erfunden! Der Benutzer hat schwachsinnige Parameter übergeben? Einfach in irgendwas umwandeln das Sinn macht. Dann kann man sich ja auch Fehlercodes als Rückgabewerte sparen weil einfach keine Funktion mehr fehlschlagen kann!
Manche programmieren ihre Controller sogar mit Arduino und nicht mit diesen altmodischen legacy erbschad Sprachen! ;-) ... Immer diese all halbjährlich wiederkehrende Diskussion zwischen Experten die ihre Fahrradschuppenfarbe bevorzugen.
Wilhelm M. schrieb: > Leider hat der Author nicht bedacht, dass > constexpr uint8_t volatile *portReg() { > return reinterpret_cast<uint8_t volatile *>(port); > } > > niemals als constexpr ausgewertet werden kann / darf, da dort ein > reinterpret_cast enthalten ist GCC inkl. Version 7.0 scheint es trotzdem zu fressen. Ist zwar als Bug markiert aber konsequent unterbunden wird es vom Compiler nicht. Außerdem sitzt der Autor im Standardkomitee und muss es ja somit wissen (oder doch nicht ?). Das er sich mit dem C-Präprozessor nicht versteht kann ich gut verstehen. Bei folgendem Makro würde ich als Compiler auch meckern:
1 | #define ledCycle(onMs, offMs) \
|
2 | (ledOn(), \
|
3 | _delay_ms(onMs), \
|
4 | ledOff(), \
|
5 | _delay_ms(offMs))
|
Christopher J. schrieb: > Wilhelm M. schrieb: >> Leider hat der Author nicht bedacht, dass >> constexpr uint8_t volatile *portReg() { >> return reinterpret_cast<uint8_t volatile *>(port); >> } >> >> niemals als constexpr ausgewertet werden kann / darf, da dort ein >> reinterpret_cast enthalten ist > > GCC inkl. Version 7.0 scheint es trotzdem zu fressen. Ist zwar als Bug > markiert aber konsequent unterbunden wird es vom Compiler nicht. Bei mir mit gcc aus git gibt es schon einen Fehler (wie in meinem Beispiel geschrieben). Und das ist dann auch das richtige Verhalten ...
:
Bearbeitet durch User
Ich hatte es selber mit Version 7.0 nicht ausprobiert und von daher kann es gut sein, dass der Compiler es doch nicht ohne weiteres frisst. Die Info war aus dem GCC Bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49171#c13 Bei GCC Version 4.7 funktioniert es aber noch reibungslos bei mir. Ist aber zugegebenermaßen auch hoffnungslos veraltet. Eventuell läuft beim Autor auch noch eine etwas ältere Version ;)
In dem Beispiel des Authors wird die Elementfunktion ja auch nicht in einem constexpr-Ausdruck ausgewertet, deswegen geht's es. Will man aber wie oben ja schon geschrieben, das Funktionsergebnis in einem constexpr-Ausdruck etwa einer constexpr-Variablen Definition verwenden, dann schlägt es - wie mindestens ab C++14 verlangt - fehl.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.