Hallo, ich interessiere mich für die Mikrocontrollerwelt, habe noch sehr wenig Erfahrung darin. Ich habe aus privatem Interesse heraus auch etwas Erfahrung mit C++ (Variablen, Datentypen, Schleifen, Funktionen, Strukturen, Zeiger). Es gibt hier zwei große Fraktionen wie man erkennen kann: AVR ud PIC. Ich tendiere eher zum PIC (warum auch immer). Aber jetzt kommt das Problem, es gibt dafür keine C++ Compiler. Was mache ich nun wenn ich C nicht kenne? C soll ja fast gleich mit C++ sein, nur wenn ich C nicht kenne weis ich auch nicht was ich nutzen kann und was nicht. Oder kennt jemand doch einen C++ COmpiler?
Dann lerne C. Mit wenig Erfahrung in C++ wirst Du mit mc nicht glücklich (und der Controller auch nicht).
Johan schrieb: > nur wenn > ich C nicht kenne weis ich auch nicht was ich nutzen kann und was nicht. da du eh lernen muss für einen µC zu programmieren, kannst du auch gleich noch C lernen. Der Compiler sagt dir schon was er nicht kennt. > Variablen, Datentypen, Schleifen, Funktionen, Strukturen, Zeiger das klingt nicht nach C++ sondern nach C. C++ sind dann Klassen, Objekte, Templates
Johan schrieb: > Ich tendiere eher zum PIC (warum auch immer). Aber > jetzt kommt das Problem, es gibt dafür keine C++ Compiler. Nicht korrekt: http://www.microchip.com/xcdemo/xcpluspromo.aspx cyno
von der Seite con Microchip:
1 | The MPLAB XC32++ compiler adds the flexibility to develop and reuse C++ projects and components for all 32-bit MCU devices with the following benefits: |
2 | |
3 | Compliant with the majority of C++98 and C++ 2003 ANSI standards |
4 | Includes Dinkumware Standard C++ Library |
5 | Can be used with all C++ or mixed C/C++ projects in MPLAB XC |
6 | All Microchip C language extensensions are available for use |
7 | |
8 | Microchip is offering a special edition of our C++ compiler software completely free for filling out a short registration. |
Peter II schrieb: > ist denn jeder pic ein 32bitter? Nein, aber PIC32 wurden im OP nicht ausgeschlossen - aber das Vorhandensein eines C++-Compilers für PIC-Mikrocontroller schon. cyno
Johan schrieb: > Es gibt hier zwei große Fraktionen wie man erkennen > kann: AVR ud PIC. Dazu kommt aber noch stark wachsend die 32 Bitter mit Cortex-M0/3/4 von ST, NXP und weiteren. Für diese gibt es gcc toolchains und C++ Bibliotheken. Und da die Cortex-M oft für kleines Geld viel Speicher haben lassen die sich auch gut mit C++ nutzen. Es gab hier auch schon ellenlange Threads über C++ auf µCs, die enden alle nur in einer üblen Schlammschlacht.
Wenn es unbedingt C++ sein soll - dann kommen eigentlich nur 32 Bit Mikrocontroller in Frage. Die Datenblätter sind so dick - da kann man nicht mehr jedes einzelne Bit kennen. Du kannst nicht mehr direkt auf der Hardware programmieren. Brauchst unbedingt die Libraries. Hat mehr Ähnlichkeit mit PC-Programmierung als mit 8-Bit-Mikrocontriller Programmierung. Pic32? Hier findest du eher Leute, die dir bei Problemen mit Stm32 weiter helfen können.
Ich hab C++ für mein letztes AVR-Projekt benutzt. Mit GCC funktionierte das ohne Probleme. Natürlich sollte man bzgl. Code-Größe die Finger von großen Template-Bibliotheken (boost) lassen und die Standard-C(++)-Bibliothek ist natürlich auch nicht so einfach da. Aber um den C-Code strukturiert hinter ein paar Klassen zu verstecken hat das gut gereicht. Ich verstehe nur nicht ganz, wie man C++ kennen kann, aber C nicht. Da im Grunde C++ eine (nicht ganz exakte) Übermenge von C ist. Daher häufig auch "C/C++" genannt. Insbesondere bzgl.: > (Variablen, Datentypen, Schleifen, Funktionen, Strukturen, Zeiger) hat sich nichts nennenswertes zwischen C++ und C verändert. Ich würde sagen, da müssen einfach nur die Kenntnisse über C/C++ vertieft werden. Angefangen bei den Grundlagen (Variablen, Datentypen, Schleifen, Funktionen, Zeiger).
Ich möchte C++ auch auf kleinere Prozessoren nicht missen. Dazu gibt es zu viele schöne Dinge an C++, die auch z.B. im AVR Bereich benutzt werden können: Klassen und Objekte zum Kapseln und Gruppieren von Daten. Konstruktoren zum sauberen Inititalisieren. Default-Parameter in Funktionen. Funktionen mit unterschiedlichen Parametern. Alles das macht den Code übersichtlicher und einfacher wartbar. Templates, Exceptions, RTTI und dynamischen Speicher kann man ja erst einmal weglassen. Und sobald man im 32-Bit Bereich ist, sollte die Codegröße auch egal sein.
> Alles das macht den Code übersichtlicher und einfacher wartbar.
Es ist zum Verzweifeln. Bei C++ bekommt man noch 10000 Features dazu,
die mehr Verwirrung als Nutzen bringen. In Java kann man die
MC-Bitfummelei nicht machen.
Ich will ein C + deine Liste an Features. Ohne diesen ganzen anderen
Kram!
Nach meiner Erfahrung (ca. 10 Jahre Embedded-Programmierung) hat C++ auf MCUs diese Größenklasse keine Vorteile, außer dass man den Code vielleicht besser lesen kann, wenn man schon viel C++-Erfahrung hat. Die echten Stärken von C++ (Templates, Vererbung, dynamische Erzeugung von Objekten usw.) sind üblicherweise auf so kleinen Architekturen nicht sinnvoll nutzbar. Wenn Du mit den etwas größeren Eisen (ARM9-Klasse oder PIC32) arbeitest, ist das natürlich eine andere Sache. Ich denke, es wird Dir nicht schwer fallen, C zu lernen, wenn Du C++ kannst. Du kannst eben keine Klassen und Objekte erzeugen sondern musst Dich auf die klassischen Funktionen beschränken. Aber bei PIC/AVR ist das sicher kein Nachteil
Cihan S. schrieb: > Ist die Arduino IDE nicht C++? in welcher Sprache die IDE geschrieben ist, spielt doch keine Rolle. Ja. mit der Arduino IDE schreibt man C++ Programme. Für AVRs ist c++ kein Problem, wenn man es will.
Nun, die Vorteile von c++ scheinen wohl endlich zu sein, im z.B. Linux-Kernel spielt es keine Rolle. Da regiert immer noch C.
... schrieb: > Nun, die Vorteile von c++ scheinen wohl endlich zu sein, > im z.B. Linux-Kernel spielt es keine Rolle. Das hat weniger mit Vorteilen als mit VorURteilen zu tun.
Historische Gründe? Damals, als Unix erfunden wurde, gabs da OOP überhaupt schon?
Ulrich F. schrieb: > Historische Gründe? > > Damals, als Unix erfunden wurde, gabs da OOP überhaupt schon? Du wirst lachen: ja Simula: erster Compiler 1964/1965 Unix: 1969
Noch einer schrieb: > Die Datenblätter sind so dick - da kann man nicht mehr jedes einzelne > Bit kennen. Du kannst nicht mehr direkt auf der Hardware programmieren. > Brauchst unbedingt die Libraries. Noch einer schrieb: > Es ist zum Verzweifeln. Bei C++ bekommt man noch 10000 Features dazu, > die mehr Verwirrung als Nutzen bringen. Beide Aussagen sprechen von einer Überforderung durch Informationen und Optionen. Du solltest hier vorsichtig sein die eigenen Grenzen zu verallgemeinern. Besonders, da ein C++ Programm nicht deswegen ein C++ Programm ist, weil es alle Möglichkeiten möglichst kompakt anwendet, sondern weil mindestens eine Fähigkeit genutzt wird, die im ursprünglichen C nur über Umwege zu realisieren ist. Jede Software, dass Klassen statt Instanz-Strukturen als Ersatz für das Klassenkonzept nutzt (siehe z.B. die ASF) würde ich vorziehen, wenn es keine andere Rahmenbedingung gibt, die dem Einsatz widerspricht. (Diese gibt es im Fall der ASF, und sie ist eher logistischer denn technischer Natur)
Karl H. schrieb: > Du wirst lachen: ja > Simula: erster Compiler 1964/1965 Ei! 64.... erster Schultag... Kein Wunder, dass das an mir vorbei gegangen ist... ;-)
Robin R. schrieb: > Ich verstehe nur nicht ganz, wie man C++ kennen kann, aber C nicht. Kann ich auch nicht so ganz nachvollziehen. Man kann in C++ prozedural programmieren - dann ist es nahezu das Gleiche wie üblicher C-Code. Und tatsächlich kann man in C auch objektorientiert programmieren, wenn man es unbedingt will. GTK+ macht's vor.
:
Bearbeitet durch User
... schrieb: > Nun, die Vorteile von c++ scheinen wohl endlich zu sein, > im z.B. Linux-Kernel spielt es keine Rolle. Auch der Windows-Kernel ist in C geschrieben. Die meisten C++-Fähigkeiten sind in einem Kernel nicht nutzbar (Exceptions) oder nur eingeschränkt sinnvoll (Templates, dynamischer Speicher), und den Kernel in C zu schreiben verhindert zuverlässig, dass ein Entwickler, der das nicht weiß, es auch nicht versucht. Im Prinzip ist das der gleiche Grund wie auf einem Mikrocontroller: Ja, es geht, aber man muss wissen, was man tut. Davon abgesehen ist es nicht sinnvoll, den Linux-Kernel auf C++ umzuschreiben, weil die Infrastruktur in C vorhanden und getestet ist und der Vorteil durch C++ den Aufwand nicht wettmacht. Das ist z.B. bei gcc anders.
:
Bearbeitet durch User
>Beide Aussagen sprechen von einer Überforderung durch Informationen und >Optionen. Du solltest hier vorsichtig sein die eigenen Grenzen zu >verallgemeinern. Nö. Ich mach das bald 40 Jahre. Hab mit Assembler auf ZX80 angefangen und dann alles mögliche gemacht. Hier handelt es sich um zwei andere Probleme. Im laufe der Jahrzehnte hat sich die Programmierung komplett geändert. In die Register eines 8-Bit Controllers, oder auch in ein DOS-Programm konnte man sich noch vollständig einarbeiten. Heutzutage ist es so umfangreich - bis man alle Detail durchgearbeitet hat, ist es schon wieder veraltet. Es spaltet sich auf - der eine schreibt Python-Libraries für Raspberry-Peripherie, der andere schreibt damit Web-Oberflächen für Steuerungen. Pic32 liegt vielleicht noch an der Grenze, wo sich einer alleine in alles einarbeiten kann. Bei Cortex-A geht das nicht mehr. Und dann kommt noch etwas total bescheuertes dazu: 20 Entwickler lösen innerhalb eines Programmes 30 gleichartige Probleme auf 40 verschiedene Arten. C++ ist da am schlimmsten. Man findet in einem Programm alles von K&R bis Java-Stil; Selbst gebastelte Container mit obskurer Garbage-Collection neben QList, STL und alten C-Arrays; Präprozessor-Tricksereinen neben Inline-Funktionen. Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut.
Das ist natürlich ein schlagkräftiges Argument: weil es manche/ viele nicht oder zu gut beherrschen, sollte man auch von dien guten Eigenschaften von C++ die Finger weg lassen. Logik ist für mich ein wesentlicher Bestandteil des Programmierens (ich verwende das Wort für den ganten Vorgang der Softwareerstellung) und muß unabhängig von der Implementierungssprache beherrscht werden. Und es gibt Abhängigkeiten: ohne Logik brauche man gar keine Programmiersprache und dann ist es egal welche man nicht brauche. Oder änderst ausgedrückt: nicht Programmieren können, kann man ihn jeder Sprache gleich gut.
Carl D. schrieb: > Das ist natürlich ein schlagkräftiges Argument: weil es manche/ > viele nicht oder zu gut beherrschen ... ist es nicht unbedingt die optimale Programmierform: Hochflexibel ja, aber dafür hochkomplex. Im Ergebnis Software die besser sein könnte. Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie nötig.
Ds C++ auch C beinhaltet ist das mal wieder eine sinnlose "Diskussion" oder besser "Talkshow". Man kann jeden µC ob 1bit, 22bit oder 666bit mit C++/c/Assembler/Fotran/XYZ programmieren. Der Compiler macht aus der "Hochsprache" erstmal passenden Assembler der dann in den OP-Code umgesetzt wird. Lediglich der Overhead bei Bibliotheken o.ä. kann zu Flashmangel führen. Man muß aber keine STL o.ä. ins µC Projekt einbauen wenn's keinen Sinn macht. C reicht idR für µC Projekte ist aber in C++ enthalten. Ergo kann man auch µC in C++ programmieren und Kapselung nutzen ohne das es einen wirklich negativen Effekt hat.
Noch einer schrieb: > Es ist zum Verzweifeln. Bei C++ bekommt man noch 10000 Features dazu, > die mehr Verwirrung als Nutzen bringen. In Java kann man die > MC-Bitfummelei nicht machen. http://www.harbaum.org/till/nanovm/index.shtml > Ich will ein C + deine Liste an Features. Ohne diesen ganzen anderen > Kram! Du mußt "diesen ganzen anderen Kram" nicht benutzen. Dann ist C++ nämlich haargenau das, was Du willst: C plus die genannte "Liste an Features".
Schlappohr schrieb: > Nach meiner Erfahrung (ca. 10 Jahre Embedded-Programmierung) hat C++ auf > MCUs diese Größenklasse keine Vorteile, außer dass man den Code > vielleicht besser lesen kann Das reicht doch schon. > Die > echten Stärken von C++ (Templates, Vererbung, dynamische Erzeugung von > Objekten usw.) sind üblicherweise auf so kleinen Architekturen nicht > sinnvoll nutzbar. Vererbung und Templates sind vollkommen problemlos nutzbar und erzeugen überhaupt keinen zusätzlichen Overhead. Aber selbst wenn Deine Prämisse zuträfe und nurmehr die Datenkapselung übrig bliebe, wäre alleine dies bereits ein hinreichend großer Vorteil für C++ auf Mikrocontrollern.
> Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie
nötig.
Zum Glück ist die Welt grösser als die Kanten deines Basteltischs. Was
glaubst denn, was das für Leute sind, die, nicht als Hoby (bewusst
gewählte Schreibweise!), die Dinge um dich herum mit Software Versehen
haben. Waren das alles Idioten? Oder gibt es doch nur einen
Geisterfahrer.
Noch einer schrieb: > Nö. Ich mach das bald 40 Jahre. Noch einer schrieb: > 20 Entwickler lösen innerhalb eines Programmes 30 gleichartige Probleme > auf 40 verschiedene Arten. Noch einer schrieb: > Einfach nur nervtötender Kleinkram. Lässt sich nicht aufräumen - während > man einen Bereich auf eine übersichtliche Lösung umstellt, werden schon > wieder 5 neue Änderungen auf 10 unterschiedliche Arten eingebaut. Das ist aber eher das Versagen eines Prozesses, welcher der Senior Developer zu führen hat. Aufgrund deiner Erfahrung sollte man annehmen, dass du weisst, dass es mit den Prozessen und Entwicklungsstrukturen steht und fällt, was für eine "Suppe" abgeliefert wird. Das Problem hättest du gar vermehrt in noch ganz anderen Sprachen, die eben noch mehr Design Pattern zulassen. Die Frage ist nun, wer macht diesen Aspekt des Jobs? Ein Projektleiter mit wenig Zeit oder Hingabe für diese "Details", ein erfahrender aber zurückhaltender Entwickler, der besser bei seinen Leisten geblieben wäre, oder ein Jungspund, der noch nicht verstanden hat, dass ohne einen festen Rahmen alles verläuft, wie die Suppe auf nem flachen Teller, oder tatsächlich ein erfahrener und führender Senior Developer?
@Sheeva Plug: > Das reicht doch schon. Wenn das eine genügend große Rolle spielt, dann ja. Aber ich nehme auch keinen Lieferwagen zum Brötchen kaufen, nur weil er eine Anhängerkupplung hat. > Vererbung und Templates sind vollkommen problemlos nutzbar und erzeugen > überhaupt keinen zusätzlichen Overhead. Aber selbst wenn Deine Prämisse > zuträfe und nurmehr die Datenkapselung übrig bliebe, wäre alleine dies > bereits ein hinreichend großer Vorteil für C++ auf Mikrocontrollern. Sicher kannst du das alles machen, aber wo ist der Nutzen? Die Komplexität eines 15000-Zeilen-Progrämmchens, das nachher ein paar kB Flash belegt, rechtfertigt kaum OOP. Besonders pikant wird die Sache, wenn Dein Controller harte Echtzeitanforderungen erfüllen muss. Wenn Du unter diesen Bedingungen anfängst, dynamisch Objekte zu erzeugen und zu vernichten, dann stehen Dir ein paar schlaflose Nächte bevor (abgesehen davon, dass z.B. PICs gar nicht genug RAM für solche Späße haben, und im Flash kannst Du nun mal nichts dynamisch anlegen). Du kannst natürlich am Anfang alle benötigten Objekte erzeugen und dann verwenden, aber dann ist Dein Programm statisch und Du kannst es genauso gut in C schreiben. Das hat zudem den Vorteil, dass Dir schon der Compiler sagt, wenn Du den Speicher sprengst. Ich will es mal so zusammenfassen: Die Verwendung von C++ auf kleinen Controllern ist letztlich Geschmackssache. Echte Vorteile gibt's kaum, weil Du meistens nur einen Subset von C++ nutzen kannst. Um auf das OP zurück zu kommen: Ich würde sicher keinen Controller danach auswählen, ob es dafür einen C++-Compiler gibt.
schlappohr schrieb: > @Sheeva Plug: > >> Das reicht doch schon. > > Wenn das eine genügend große Rolle spielt, dann ja. Aber ich nehme auch > keinen Lieferwagen zum Brötchen kaufen, nur weil er eine > Anhängerkupplung hat. Und nicht alles was hinkt ist ein Vergleich. Besserer Vergleich (wenn es den schon ein Vergleich, statt Argumente, sein muss), wäre: Ich bin froh über meinen Gurt im Auto und benutze Ihn nicht nur auf der Autobahn, sondern auch auf dem Weg zum Bäcker. > Sicher kannst du das alles machen, aber wo ist der Nutzen? Die Aussage "Das reicht doch schon." von Sheeva bezog sich auf: "außer dass man den Code vielleicht besser lesen kann". Lesbarer Code ist ein Nutzen, auch in "15000-Zeilen-Progrämmchen". > Wenn Du > unter diesen Bedingungen anfängst, dynamisch Objekte zu erzeugen und zu > vernichten, dann stehen Dir ein paar schlaflose Nächte bevor das hat überhaupt niemand vorgeschlagen. "Vererbung und Templates" lassen sich ganz hervorragend ohne dynamische Speicherverwaltung nutzen. > Ich will es mal so zusammenfassen: Die Verwendung von C++ auf kleinen > Controllern ist letztlich Geschmackssache. Echte Vorteile gibt's kaum, Wenn es Vorteile gibt, dann nutze ich sie. Einige C compiler sind eh nur noch abgespeckte C++ compiler, wenn ich so einen C compiler habe, muss ich nur noch die Dateien anders benennen und ein anderen Compiler-Schalter setzen um diese Vorteile zu nutzen: - keine implizite Konvertierung von void* - namespaces - templates - überladende Funktionen - Operatoren für eigene Typen - typesichere enums - //-Kommentare - constexpr - Konstruktoren / Destruktoren - umfangreichere Standardlibraries: - crc - random number generators - algorithmen (Suchen, Sortieren, Permutieren...) Alles für "umsonst" zu haben. Ansonsten lässt sich C++ auch ganz hervorragen in der Verbindung mit C verwenden. > weil Du meistens nur einen Subset von C++ nutzen kannst. Um auf das OP > zurück zu kommen: Ich würde sicher keinen Controller danach auswählen, > ob es dafür einen C++-Compiler gibt. Das liegt eher an dem Subset von C++, das Du kennst. mfg Torsten
Torsten R. schrieb: > Compiler-Schalter setzen um diese Vorteile zu nutzen: > > - keine implizite Konvertierung von void* > - namespaces > - templates > - überladende Funktionen > - Operatoren für eigene Typen > - typesichere enums > - //-Kommentare > - constexpr > - Konstruktoren / Destruktoren > - umfangreichere Standardlibraries: > - crc > - random number generators > - algorithmen (Suchen, Sortieren, Permutieren...) - Möglichkeit der Datenkapselung mit private und protected (ja, ich weiss, man kann sie umgehen) und inline Gettern/Settern -> kein runtime Penalty und trotzdem kann ich wilden Zugriffen auf Variblen einen Riegel vorschieben. Zum Thema: 15 Programmierer lösen dieselbe AUfgabe auf 40 verschiedene Arten: Das Problem hast du in C genauso. Das ist kein Problem der Sprache sondern ein Problem der Teamführung. Code Review von Anfang an und regelmässige Meetings in denen Richtlinien ausgegeben werden, schaffen da schnell Abhilfe. Muss man sich in einem Code Review verantworten, dann werden auch weniger 'Schweinereien' gemacht, in denen Mechanismen absichtlich ausgehebelt werden.
:
Bearbeitet durch User
schlappohr schrieb: > Du kannst > natürlich am Anfang alle benötigten Objekte erzeugen und dann verwenden, > aber dann ist Dein Programm statisch und Du kannst es genauso gut in C > schreiben. Wie bitte? Ob Objekte dynamisch oder statisch erzeugt werden, sagt nun wirklich nichts darüber aus, welche Sprache sinnvoll ist. Umgekehrt zwingt einem die Sprache auch keine dynamische Allozierung auf. Auch in vielen grösseren C++-Projekten braucht man höchst selten dynamische Speicherallokation mit 'new' oder dessen RAII-Wrappern. Dass man mit so viel Halbwissen alle drei Wochen einen Thread mit 500 Beiträgen füllen kann, ist schon amüsant.
schlappohr schrieb: > Wenn das eine genügend große Rolle spielt, dann ja. Aber ich nehme auch > keinen Lieferwagen zum Brötchen kaufen, nur weil er eine > Anhängerkupplung hat. Abgesehen davon, daß die Sinnhaftigkeit eines Lieferwagens und seiner Anhängerkupplung zum Brötchenholen direkt von der Menge der zu kaufenden Brötchen abhängt, bleiben mir der Sinn sowie der Realitätsbezug dieses merkwürdigen Vergleiches leider verschlossen. >> Vererbung und Templates sind vollkommen problemlos nutzbar und erzeugen >> überhaupt keinen zusätzlichen Overhead. Aber selbst wenn Deine Prämisse >> zuträfe und nurmehr die Datenkapselung übrig bliebe, wäre alleine dies >> bereits ein hinreichend großer Vorteil für C++ auf Mikrocontrollern. > > Sicher kannst du das alles machen, aber wo ist der Nutzen? Die > Komplexität eines 15000-Zeilen-Progrämmchens, das nachher ein paar kB > Flash belegt, rechtfertigt kaum OOP. Muß man OOP jetzt rechtfertigen? So ein Unsinn. OOP ist nur ein Paradigma zur Organisation von Sourcecode, um die Wiederverwendbarkeit, Wartbarkeit und Übersichtlichkeit zu verbessern. Daß die OOP hilft, diese Designziele besser und einfacher umzusetzen als mit anderen Paradigmen, genügt schon, um ihren Einsatz in jeder möglichen Umgebung nicht nur zu rechtfertigen, sondern sogar zu empfehlen. Für alle Entwickler, die dieses ausgesprochen mächtige und leistungsfähige Werkzeug beherrschen, ist die OOP eine große Vereinfachung und Erleichterung ihrer Arbeit. > Besonders pikant wird die Sache, wenn Dein Controller harte > Echtzeitanforderungen erfüllen muss. Auch das ist mit C++ überhaupt kein Problem -- jedenfalls kein größeres, als es mit C eins wäre. Zum Glück kann man, wenn man die genaue Kontrolle über die verbrauchten Taktzyklen benötigt, selbstverständlich problemlos auch Assembler-Code in C++ integrieren -- genau wie in C. > Wenn Du unter diesen Bedingungen anfängst, dynamisch Objekte zu erzeugen > und zu vernichten, dann stehen Dir ein paar schlaflose Nächte bevor So ein Unsinn. Die dynamische Erzeugung und Zerstörung von Objekten hat zunächst einmal überhaupt gar nichts mit der OOP zu tun. Kennst Du C's "malloc()"- und "free()"-Funktionen nicht? Die werden im Mikrocontroller-Umfeld auch selten genutzt. Allerdings nicht, weil dafür nicht genügend Rssourcen zur Verfügung stehen, sondern weil das bei den meistens eher einfachen Mikrocontroller-Programmen nicht notwendig ist. Und genau aus demselben Grund braucht man das auch mit C++ oder anderen OO-Sprachen in diesem Umfeld eher selten. Möglich und ganz, ganz selten sogar sinnvoll ist es aber trotzdem, und ich habe das auch schon ganz ohne schlaflose Nächte benutzt. Trotzdem Dank für Deine Sorge um meine Nachtruhe. > Ich will es mal so zusammenfassen: Die Verwendung von C++ auf kleinen > Controllern ist letztlich Geschmackssache. Echte Vorteile gibt's kaum, > weil Du meistens nur einen Subset von C++ nutzen kannst. Um auf das OP > zurück zu kommen: Ich würde sicher keinen Controller danach auswählen, > ob es dafür einen C++-Compiler gibt. Ich schon. Weil nämlich die Untermenge von OOP-Features, die auf einem Mikrocontroller sinnvoll und gewinnbringend genutzt werden können, so umfangreich und nützlich ist, daß sich die OOP in den meisten Fällen einfach lohnt und signifikante Vorteile bietet. Daß die sich dem Laien möglicherweise nicht erschließen, spricht nicht gegen ihre Existenz. Keine Frage: auf Mikrocontrollern (und auch in den meisten anderen Fällen) geht es auch ohne OOP. Aber mit geht es fast immer viel leichter.
Nimm halt nicht so einen grottigen Controller. PIC und AVR sind Relikte aus dem letzten Jahrtausend. Schau dir mal die Gecko Reihe von Silabs oder die STM32 an. DAS sind Controller auf denen man arbeiten möchte. Ggf. noch MSP430 mit FRAM von TI. Der AVR Kram ist aufm Arduino oder so noch ok, aber wenn man wirklich damit arbeiten möchte sind diese in meinen Augen nicht mehr zeitgemäß. Und sollte jetzt die Fraktion "aber wenn 8bit reichen" auftauchen: Dann arbeitet gefälligst gleich mit einem 8051, der ist dann sicher auch ausreichend und in der Massenproduktion bestimmt auch viel billiger. Aber hier im Hobbybereich und auch in vielen Firmen tut man sich mit ARM einen Gefallen, allein schon der Segger J-Link Edu für 50€ ist Gold wert im Vergleich zu den Debuggern von Microchip (tolle GPL Violation begehen die übrigens) oder Atmel.
Der einfachste Weg um als Neuling mit C++ auf einem Controller zu starten ist Arduino.
Michael schrieb: > Der einfachste Weg um als Neuling mit C++ auf einem Controller zu > starten ist Arduino. Wobei Arduino eine recht schlechte C++-Umsetzung für den Zugriff auf die AVR-Hardware verwendet. Mit ein bischen mehr C++ (Templates etc) hätte man das "digitalWrite" usw. so hinkriegen können, dass der GCC es zu exakt einer ASM-"Set-Bit"-Instruktion optimiert. So befeuert Arduino nur die Vorurteile, dass C++ auf µC "zu langsam" sei.
Planlos schrieb: > So befeuert Arduino nur die Vorurteile, dass C++ auf µC "zu langsam" > sei. Michael schrieb ja auch vom "einfachsten" Weg, nicht dem besten Weg ;-) SCNR
Wie immer verläuft auch diese Diskussion, wenn es um C versus C++ geht. Man könnte meinen, dass Diskussionen sinnlos seien - vor allem in diesem Forum. Darf ich anregen, das Thema PIC versus AVR versus ARM nochmal zu vertiefen? :-)
Stefan U. schrieb: > Darf ich anregen, das Thema PIC versus AVR versus ARM nochmal zu > vertiefen? :-) Ja, bitte! Ich überlege schon die ganze Zeit, ob ich mir mit meinen Arduinos und AVR DILs einen Gefallen tue. Und obs nicht evtl. besser wäre sich mal STM32 anzusehen für meinen Briefkasten-Melder mit Blink-LED. Aber 3,3V vs. meine ganzen 5V-Bauteile ist dann auch wieder ein Problem. Oder soll ich gleich 1,8V nehmen, weil 3,3V schon nicht mehr "Zeitgemäß" ist? ;-)
Robin R. schrieb: > Und obs nicht > evtl. besser wäre sich mal STM32 anzusehen für meinen Briefkasten-Melder > mit Blink-LED. Nenene... immer der größten Community folgen! Der logische Schritt ist Arduino --> RaspberryPI, nicht AVR --> STM32!
Noch einer schrieb: > Die Datenblätter sind so dick - da kann man nicht mehr jedes einzelne > Bit kennen. Du kannst nicht mehr direkt auf der Hardware programmieren. > Brauchst unbedingt die Libraries. Hat mehr Ähnlichkeit mit > PC-Programmierung als mit 8-Bit-Mikrocontriller Programmierung. So ein Unsinn. Schau bitte mal ins Reference-Manual eines beliebigen ARM Cortex-Mx Controllers. Die Controller sind kaum komplexer als die gängigen 8Bit Mikrocontroller, allerdings kann die Peripherie oft mehr. Die Libraries braucht man ebenfalls nicht. Karl H. schrieb: >> Compiler-Schalter setzen um diese Vorteile zu nutzen: >> >> - keine implizite Konvertierung von void* >> - namespaces >> - templates >> - überladende Funktionen >> - Operatoren für eigene Typen >> - typesichere enums >> - //-Kommentare >> - constexpr >> - Konstruktoren / Destruktoren >> - umfangreichere Standardlibraries: >> - crc >> - random number generators >> - algorithmen (Suchen, Sortieren, Permutieren...) > > - Möglichkeit der Datenkapselung mit private und protected (ja, ich > weiss, man kann sie umgehen) und inline Gettern/Settern -> kein runtime > Penalty und trotzdem kann ich wilden Zugriffen auf Variblen einen Riegel > vorschieben. - static_assert
Planlos schrieb: > Michael schrieb: >> Der einfachste Weg um als Neuling mit C++ auf einem Controller zu >> starten ist Arduino. > > Wobei Arduino eine recht schlechte C++-Umsetzung für den Zugriff auf die > AVR-Hardware verwendet. Eigentlich nicht. Ja, im Vergleich zu anderen Lösungsmöglichkeiten ist das ineffizient, aber das Designziel der Arduino-Umgebung war und ist ja nicht die Effizienz, sondern die Einfachheit. Kernthema des Arduino-Projekts ist schließlich, die Welt der Mikrocontroller-Programmierung auch für weniger technikaffine Menschen möglichst einfach zugänglich zu machen, und dieses Ziel wurde IMHO hervorragend erreicht. > Mit ein bischen mehr C++ (Templates etc) hätte man das "digitalWrite" > usw. so hinkriegen können, dass der GCC es zu exakt einer > ASM-"Set-Bit"-Instruktion optimiert. Ja. Aber das hätte dem Designziel widersprochen. Aber wenn Du möchtest, kannst Du auch in der Arduino-Umgebung an den Bits herumpopeln, um die maximale Effizenz bei minimaler Codegröße zu erreichen.
Sheeva P. schrieb: > Eigentlich nicht. Ja, im Vergleich zu anderen Lösungsmöglichkeiten ist > das ineffizient, aber das Designziel der Arduino-Umgebung war und ist ja > nicht die Effizienz, sondern die Einfachheit. was wäre an der ineffizienteren Lösung komplizierter gewesen? Man hätte beides haben können.
> was wäre an der ineffizienteren Lösung komplizierter gewesen?
Warscheinlich die Entwicklungszeit und damit weniger Profit.
Sheeva P. schrieb: > Aber das hätte dem Designziel widersprochen. Naja... Wenn man z.B. bereit wäre, statt
1 | LiquidCrystal lcd(12, 11, 5, 4, 3, 2); |
etwas in dieser Art zu schreiben:
1 | LiquidCrystal<12, 11, 5, 4, 3, 2> lcd; |
dann hätte der Compiler viel viel mehr Möglichkeiten zur Optimierung. Ok, Compile-Zeit steigt dabei etwas an, aber solang man nicht grad einen ganzen Sack von LCDs gleichzeitig am Arduino betreiben will, spart man enorm Flash. und soooo viel komplizierter wäre die zweite Schreibweise auch nicht. Davon abgesehen, dass die sowieso in 99% der Fälle durch Copy&Paste aus dem Tutorial in den Programmcode wandert.
Der Arduino Jünger, erwartet, dass ein digitalWrite() den pin auch auf das gewünschte Potential zieht. Und das bekommt er! Dazu muss digitalWrite(), unter Umständen, eine auf dem Pin laufende PWM abschalten. Planlos schrieb: > Wenn man z.B. bereit wäre, > stattLiquidCrystal lcd(12, 11, 5, 4, 3, 2); > > etwas in dieser Art zu schreiben:LiquidCrystal<12, 11, 5, 4, 3, 2> lcd; Ach, das ist ja nur eine Lib... Die kann man sich machen, wie man will... Und vielleicht wirds ja mal so umgesetzt. Andere Libs machen das schon so.
Carl D. schrieb: >> Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie nötig. > Zum Glück ist die Welt grösser als die Kanten deines Basteltischs. Was > glaubst denn, was das für Leute sind, die, nicht als Hoby (bewusst > gewählte Schreibweise!), die Dinge um dich herum mit Software Versehen > haben. Waren das alles Idioten? Oder gibt es doch nur einen > Geisterfahrer. Eine adäquate Antwort auf mein Argument war das nun nicht gerade ... Und schau Carl, kein Basteltisch der Welt existiert für sich allein. Da gelten die gleichen Gesetze so wie überall. Man sollte sich immer vom Verstand inspirieren lassen- und nicht von blinder Emotion so wie Du gerade. Stefan U. schrieb: > Man könnte meinen, dass Diskussionen sinnlos seien - vor allem in diesem > Forum. > Darf ich anregen, das Thema PIC versus AVR versus ARM nochmal zu > vertiefen? :-) Nein sind sie ganz und gar nicht. Es könnte um ganz grundlegende Weichenstellungen gehen! Ich möchte anregen, immer die realen Bedürfnisse der konkreten oder zukünftig geplanten App im Auge zu behalten. Sie ist es doch, die letztlich nützt, die motivieren und keine unnötige, kontraproduktiv frustrierende Arbeit machen soll. Deshalb ist Einfachheit so wichtig. Dann kommt der Spaß von ganz allein!
Moby A. schrieb: > Carl D. schrieb: >>> Weil die Praxis die ist, daß es nicht allzuviele so beherrschen wie nötig. > >> Zum Glück ist die Welt grösser als die Kanten deines Basteltischs. Was >> glaubst denn, was das für Leute sind, die, nicht als Hoby (bewusst >> gewählte Schreibweise!), die Dinge um dich herum mit Software Versehen >> haben. Waren das alles Idioten? Oder gibt es doch nur einen >> Geisterfahrer. > > Eine adäquate Antwort auf mein Argument war das nun nicht gerade ... Weil deine Aussage schon Quatsch war. Deine Ansage war, dass nicht allzuviele eine Sprache wie C++ gut genug beherrschen. Das ist Unsinn. Es gibt jede Menge C++ Programmierer, die ihr Werkzeug mehr als ausreichend gut beherrschen. Du tust gerade so, als ob das Raketentechnik wäre, für die es weltweit nur eine Handvoll Spezialisten gibt. Dem ist nicht so. Lass dich nicht vom Forum hier in die Irre führen. Wir sehen hier nur die, die zu faul oder zu arrogant sind, ihre Programmiersprache auch zu erlernen. Zumal es für die µC Programmierung da gar nicht so viel aus der Sprache benötigt. Auf jeden, der hier hilfesuchend aufschlägt, kommen tausende, die mehr als genügend Ahnung haben.
Karl H. schrieb: > Lass dich nicht vom Forum hier in die Irre führen. Wir sehen hier nur > die, die zu faul oder zu arrogant sind, ihre Programmiersprache auch zu > erlernen. Zumal es für die µC Programmierung da gar nicht so viel aus > der Sprache benötigt. Auf jeden, der hier hilfesuchend aufschlägt, > kommen tausende, die mehr als genügend Ahnung haben. Und wenn ich das hinzufügen darf: Die Programmiersprache ist letzten Endes nur ein Werkzeug. Ein Werkzeug um damit Algorithmen zu implementieren. Und da fängt dann Informatik erst richtig an. Das was du unter Optimierung verstehst, das sind alles nur Peanuts in Relation dazu, was man mittels Algorithmen-Arbeit noch aus einem Computer herausholen kann. Auf diese Ebene wirst du aber nie vorstossen, wenn du deine Zeit damit verplemperst dir zu überlegen welcher Branch Befehl denn jetzt eigentlich der richtige wäre und wie der vorhergehende Compare gestaltet sein muss, damit du 2 Taktzyklen einsparen kannst, die global gesehen völlig irrelevant sind. Ein Quicksort schlägt einen Bubblesort nicht deswegen, weil die Vergleichsbefehle so taktsparend programmiert wären. Ein Travelling Salesman ist nicht deswegen schwer, weil man nicht wüsste, wie man Speicher schnell indirekt adressieren könnte. Ein Simplex lebt nicht davon, dass Array Operationen besonders taktsparend implementiert werden können. Da gibt es noch eine ganze Wissens-Welt, die auf dich wartet und die es zu erforschen gilt.
:
Bearbeitet durch User
@Sheeva Plug > [...]bleiben mir der Sinn sowie der Realitätsbezug dieses > merkwürdigen Vergleiches leider verschlossen. Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen braucht. Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen MCU sinnvoll nutzen kann. Sorry wenn das zu kompliziert war. > Muß man OOP jetzt rechtfertigen? So ein Unsinn. OOP ist nur ein Wenn ich als Projektleiter entscheiden soll, ob wir auf eine andere Controller-Architektur umsteigen, die ein anderes Konzept hat, teurer ist, Einarbeitung in eine neue Toolchain erfordert und am Ende dasselbe leistet, und das nur weil jemand C++ toll findet, ja, dann verlange ich eine Rechtfertigung. Für einen Hobbybastler mag das vielleicht keine Rolle spielen. > OOP ist nur ein > Paradigma zur Organisation von Sourcecode, um die Wiederverwendbarkeit, > Wartbarkeit und Übersichtlichkeit zu verbessern. <Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++ Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem, das nur Sinn macht, wenn Du es auch nutzt. Die komfortablen Sprachlemente bezahlst Du immer mit einem ineffizienteren Maschinencode (bei jeder Sprache). Das ist einer der Gründe, warum viele MCU-Hersteller eben (noch) keinen C++-Compiler anbieten. > Auch das ist mit C++ überhaupt kein Problem -- jedenfalls kein größeres, Ich rede nicht von Assembler-Inlining. Ich rede davon, dass Code, der dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit schwieriger vorherzusagen ist. Deswegen wird in RT-Systemen üblicherweise alles so weit wie möglich statisch gemacht, und damit geht ein wesentlicher Vorteil von C++ verloren. Dabei sind dynamische Objekte nur ein Aspket von vielen. Realtime-C++ ist ein ziemlicher Act, da gibt es ganze Fachbücher drüber. Und der allgemeine Konsens ist: Wenn es nicht unbedigt sein muss, dann lass es sein. Es gibt ein nettes Zitat von Linux Torvalds: "writing kernel code in C++ is a BLOODY STUPID IDEA [...]" und das, obwohl Linux nicht mal echtzeitfähig ist. Noch ein schönes Zitat von einer Webseite von Texas Instruments: "Do not think that Embedded C++ code is always more efficient. Even the C++ features allowed by Embedded C++ can be used poorly, with ill effect. The bad news is you have to understand the efficiency aspects of the C++ code you write.[...]". Deine OOP-Always-and-Everywhere-These solltest Du also nochmal überdenken. > Kennst Du C's "malloc()"- und "free()"-Funktionen nicht? Die werden im Das ist jetzt aber nicht Dein Ernst, oder? malloc reserviert Speicher, das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht. Der Aufruf eines Konstruktors legt Datenstrukturen an, kopiert Code falls notwendig und ruft Initialiserungsfunktionen und weitere Konstrktoren auf. Je nach Art der Klasse ist das geringfügig komplizierter, stimmst Du mir da zu? > Die werden im > Mikrocontroller-Umfeld auch selten genutzt. Allerdings nicht, weil dafür > nicht genügend Rssourcen zur Verfügung stehen, sondern weil das bei den > meistens eher einfachen Mikrocontroller-Programmen nicht notwendig ist. So ist es. Genau das ist der Punkt. Und jetzt erklär mir mal bitte, warum Du unbedingt einen Compiler verwenden willst, der dynamische Objekte unterstützt, obwohl Du die nie brauchst. Oder Exceptions. Oder dynamische Typprüfung. Wenn Du einen Compiler hast, der das alles kann, ok. Aber warum Du die Entscheidung für einen Prozessortyp davon abhängig machen willst, kann ich nicht nachvollziehen.
C++ ist eine der komplexesten Programmiersprachen, die es gibt. Für einen MCU-Anfänger ist C++ daher ein gutes Mittel, um den Frust zu maximieren. Gerade auch wenn man ganz unbedarft anfängt, C++ wie auf dem PC zu nutzen.
schlappohr schrieb: > @Sheeva Plug > > >> [...]bleiben mir der Sinn sowie der Realitätsbezug dieses >> merkwürdigen Vergleiches leider verschlossen. > > Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen > braucht. > Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen > MCU sinnvoll nutzen kann. > Sorry wenn das zu kompliziert war. Ja ok. Aber wenn ich keinerlei Nachteile damit habe, mit dem Lieferwagen zu fahren, dann spricht auch nichts dagegen ihn zu benutzen. > Wenn ich als Projektleiter entscheiden soll, ob wir auf eine andere > Controller-Architektur umsteigen, die ein anderes Konzept hat, teurer > ist, Einarbeitung in eine neue Toolchain erfordert und am Ende dasselbe > leistet, und das nur weil jemand C++ toll findet, versteh ich nicht. Was hat jetzt die andere Controller-Architektur mit C++ zu tun? Die einzig relevante Frage lautet: gibt es dafür einen C++ Compiler - ja oder nein? Und dieselbe Frage stellt sich auch bei einem C Compiler. > <Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++ > Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere > Speicherverwaltung. Äh. Nein. > Sie haben ein komplizierteres Runtimesystem, das nur > Sinn macht, wenn Du es auch nutzt. Aber der springende Punkt ist doch: wenn ich nicht will, dann muss ich Teile davon nicht nutzen. Auch für C++ gilt: You don't pay for what you don't use. > Die komfortablen Sprachlemente > bezahlst Du immer mit einem ineffizienteren Maschinencode (bei jeder > Sprache). Wo hast du denn das her? Soll heissen: dieses Vorurteil hält sich schon so lange, so lange es C++ Compiler gibt. Richtig wird es dadurch aber auch nicht. > Das ist einer der Gründe, warum viele MCU-Hersteller eben > (noch) keinen C++-Compiler anbieten. ? Da viele MCU Hersteller als allererstes auf den gcc setzen anstatt eine Eigenentwicklung zu starten, ist das ein etwas müdes Argument. Eines ist natürlich klar: ein C Compiler ist schneller entwickelt als ein C++ Compiler. Allerdings muss man das auch nicht. Mit dem gcc steht ein Werkzeug zur Verfügung, mit dem ein C++ Compiler auch nicht mehr Aufwand ist als ein C Compiler, weil nur das Backend angepasst werden muss. Dann geht zb auch Fortran damit in einem Aufwasch. > Ich rede nicht von Assembler-Inlining. Ich rede davon, dass Code, der > dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit > schwieriger vorherzusagen ist. Ja. Und wir reden davon, dass das in C auch nicht anders ist, WENN du dynamisch zur Laufzeit Objekte erzeugst. Die Lösung ist da wie dort dieselbe: tus einfach nicht, wenn du nicht musst! > Deswegen wird in RT-Systemen > üblicherweise alles so weit wie möglich statisch gemacht, und damit geht > ein wesentlicher Vorteil von C++ verloren. Und wie gezeigt und aufgezählt wurde, bleibt dann von C++ immer noch genügend übrig, was einen Einsatz rechtfertigen kann. > Das ist jetzt aber nicht Dein Ernst, oder? malloc reserviert Speicher, > das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht. Ja. Und. Was dankst du was new macht? Genauso einen Eintrag in eine Tabelle. Und zusätzlich wird noch ein Konstruktor aufgerufen, wenn es sich um ein Klassenobjekt handelt, das über einen Konstruktor verfügt. > Der > Aufruf eines Konstruktors legt Datenstrukturen an, kopiert Code falls > notwendig Ah. Nein. COde wird da überhaupt nicht kopiert. Und die Datenstruktur (genauer der Speicher dafür) existiert schon, wenn der Konstruktor aufgerufen wird. Das ist der Teil der Objektinstanziierung, der mittels new gemacht wurde, WENN das Objekt dynamisch erzeugt wurde. Der Unterschied zwischen
1 | class A |
2 | {
|
3 | public:
|
4 | A() : i_ = 5 {} |
5 | |
6 | private:
|
7 | int i_; |
8 | };
|
9 | |
10 | int main() |
11 | {
|
12 | A myA; |
13 | }
|
und
1 | struct A |
2 | {
|
3 | int i_; |
4 | };
|
5 | |
6 | void init( struct A* pA ) |
7 | {
|
8 | pA->i_ = 5; |
9 | }
|
10 | |
11 | int main() |
12 | {
|
13 | A myA; |
14 | |
15 | init( &myA ); |
16 | }
|
ist ein rein syntaktischer. Der daraus resultierende Maschinencode ist sehr wahrscheinlich Byte für Byte identisch. Wenn überhaupt, dann werden sich Unterschiede in der hinzugelinkten Runtime feststellen lassen. Diesen Preis zahlt man allerdings nur einmal pro Programm. > und ruft Initialiserungsfunktionen und weitere Konstrktoren > auf. Ja und? Wenn du in C eine init Funktion hast, die dir eine komplexe Datenstruktur initialisiert, dann ist das doch genau dasselbe! Der einzige Unterschied: In C kannst du den Aufruf als Programmierer vergessen, in C++ kannst du es nicht vergessen. Und wenn ich mal so zurückdenke, wieviele Bugs auf das Konto von vergessenen Initialisierungen gehen, dann bin ich heilfroh, wenn mir der Compiler nach jeder Objekt-Instanziierung (die genau gleich abläuft wie in C) eine entsprechende Init-Funktion automatisch und ohne das ich daran denken muss, einbaut. > Je nach Art der Klasse ist das geringfügig komplizierter, stimmst > Du mir da zu? Klar, stimmt da jeder zu. Aber das ist doch gar nicht der springende Punkt. Der springende Punkt ist, dass du für eine komplizierte Initialisierung in C genauso den enstprechenden COde aufrufen musst. Gibt es keine Initialisierung, dann bezahlst du auch in C++ keinen Preis dafür. Der SPeicher wird allokiert und das wars. Genau gleich wie in C.
:
Bearbeitet durch User
schlappohr schrieb: > Sie haben ein komplizierteres Runtimesystem, das nur > Sinn macht, wenn Du es auch nutzt. Die komfortablen Sprachlemente > bezahlst Du immer mit einem ineffizienteren Maschinencode Das ist falsch und leider immernoch ein sehr verbreitetes Vorurteil. Ineffizienter Maschinencode wird durch ineffiziente Programmierung hervorgerufen, nicht durch die Sprache. schlappohr schrieb: > Es gibt ein nettes Zitat von Linux Torvalds: "writing kernel code > in C++ is a BLOODY STUPID IDEA [...]" und das, obwohl Linux nicht mal > echtzeitfähig ist. Nett ist ein blödes Wort, wenn etwas aus dem Kontext gerissen wird. Hat auch nichts mit echtzeit zu tun gehabt, als er das sagte. schlappohr schrieb: > Noch ein schönes Zitat von einer Webseite von Texas > Instruments: "Do not think that Embedded C++ code is always more > efficient. Even the C++ features allowed by Embedded C++ can be used > poorly, with ill effect. Das ist tatsächlich schön, sagt es doch, dass man auch mit C++ schlecht programmieren kann, aber im normalfall nicht ;-) schlappohr schrieb: > malloc reserviert Speicher, > das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht. Genau und der ganze Rest muss dann zu Fuss gegangen werden. schlappohr schrieb: > So ist es. Genau das ist der Punkt. Und jetzt erklär mir mal bitte, > warum Du unbedingt einen Compiler verwenden willst, der dynamische > Objekte unterstützt, obwohl Du die nie brauchst. C (Pre)Compiler unterstützen auch alle XMakros obwohl die weitgehend unbekannt sind. Sollte man diese Compiler nur alle nicht mehr benutzen, weil sie etwas unterstützen, dass man nicht braucht?
Karl H. schrieb: > Da gibt es noch eine ganze Wissens-Welt, die auf dich wartet und die es > zu erforschen gilt. Wissenswelten warten viele. Viel zu viele. Die Frage ist doch aber gerade: Was braucht man davon? Deshalb rücke ich die konkrete App ja so vehement in den Fokus. Uns schließlich: Das Wissen, von dem wir hier reden ist zu guten Teilen auch Wissen über aktuelle Sprachfeatures und Werkzeuge. Wissen, daß sich schnell wieder ändert und vieles in der Versenkung verschwindet. Deshalb: Klären: Was brauch ich wirklich ?!!! Darüber hinaus interessieren kann man sich gern noch für vieles. Hardware- und Softwareentwicklung sind spannend. Wenn nicht so vieles wieder vergänglich wäre... Für die tägliche Praxis bedeutet das: Bloß nicht verzetteln! Konzentration auf das Wesentliche!
schlappohr schrieb: > Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen > MCU sinnvoll nutzen kann. Zwingt dich jemand dazu alle zu nutzen? Heißt das also, wenn ich nicht alle Features von C nutze, soll ich doch lieber die Finger davon lassen? schlappohr schrieb: > <Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++ > Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere > Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem, das nur > Sinn macht, wenn Du es auch nutzt. Die komfortablen Sprachlemente > bezahlst Du immer mit einem ineffizienteren Maschinencode (bei jeder > Sprache). Das ist einer der Gründe, warum viele MCU-Hersteller eben > (noch) keinen C++-Compiler anbieten. Das kompliziertere Runtimesystem rührt aber von Exceptions und RTTI her und nicht OOP. Schalte Exceptions und RTTI aus, dann hast du die gleichen Bedingungen wie unter C. Und nein komfortable Sprachelemente erzeugen eben nicht pauschal ineffizienten Maschinencode, einige lassen sich nämlich zur Kompilierung auflösen. In C++ gibts eine Menge Sprachelemente, die zur Laufzeit nichts kosten. schlappohr schrieb: > Ich rede davon, dass Code, der > dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit > schwieriger vorherzusagen ist. Deswegen wird in RT-Systemen > üblicherweise alles so weit wie möglich statisch gemacht, und damit geht > ein wesentlicher Vorteil von C++ verloren. Dann schreib halt keinen Code, der Objekte zur Laufzeit erzeugt. Da lassen sich immer noch viele (fast alle?) C++ Features nutzen. schlappohr schrieb: > Und der > allgemeine Konsens ist: Wenn es nicht unbedigt sein muss, dann lass es > sein. Es gibt ein nettes Zitat von Linux Torvalds: "writing kernel code > in C++ is a BLOODY STUPID IDEA [...]" Da gibt es keinen "allgemeinen" Konsens. Im übrigen sind Torvalds aussagen dazu sehr umstritten. schlappohr schrieb: > So ist es. Genau das ist der Punkt. Und jetzt erklär mir mal bitte, > warum Du unbedingt einen Compiler verwenden willst, der dynamische > Objekte unterstützt, obwohl Du die nie brauchst. Ja himmel Hergott, weil es andere Features gibt (siehe oben) die mir C nicht bieten kann.
schlappohr schrieb: > Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen > braucht. > Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen > MCU sinnvoll nutzen kann. > Sorry wenn das zu kompliziert war. Das ist immer so das Problem mit Vergleichen. Du wolltest wohl sagen, das die Kosten für die Nutzung eines C++ compilers gegenüber eines C compilers (Lieferwagen vs. Fahrrad) höher ist, bei gleichem Nutzen (Brötchen). Das kann aber niemand verstehen, der nicht der Meinung ist, dass dem so ist. Wenn Du der Meinung bist, dass die Kosten für die Nutzung eines C++ Compilers höher sind, dann sag es doch so und bringe einfach konkrete Aspekte. Es hat ja schon seinen Grund, warum Vergleiche hauptsächlich in der Politik und Theologie verwendet werden ;-) > Für einen Hobbybastler mag das vielleicht keine > Rolle spielen. Uhhh, Faul! > C++ > Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere > Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem, das nur > Sinn macht, wenn Du es auch nutzt. Ich habe gerade mal bei einem nicht trivialen C++ Beispiel alle system libraries raus geworfen. Das ist der Teil, den ich gegenüber einer C-Lösung hinzu fügen musste:
1 | extern "C" void __cxa_pure_virtual(void) {} |
2 | |
3 | extern "C" void (*__preinit_array_start []) (void) __attribute__((weak)); |
4 | extern "C" void (*__preinit_array_end []) (void) __attribute__((weak)); |
5 | extern "C" void (*__init_array_start []) (void) __attribute__((weak)); |
6 | extern "C" void (*__init_array_end []) (void) __attribute__((weak)); |
7 | extern "C" void (*__fini_array_start []) (void) __attribute__((weak)); |
8 | extern "C" void (*__fini_array_end []) (void) __attribute__((weak)); |
9 | |
10 | extern "C" typedef void (*vector)(); |
11 | |
12 | extern "C" void _start(void) { |
13 | extern int main(void); |
14 | |
15 | |
16 | for ( vector* init = &__preinit_array_start[ 0 ]; init != &__preinit_array_end[ 0 ]; ++init ) |
17 | (*init)(); |
18 | |
19 | for ( vector* init = &__init_array_start[ 0 ]; init != &__init_array_end[ 0 ]; ++init ) |
20 | (*init)(); |
21 | |
22 | main(); |
23 | |
24 | for ( vector* finit = &__fini_array_start[ 0 ]; finit != &__fini_array_end[ 0 ]; ++finit ) |
25 | (*finit)(); |
26 | |
27 | }
|
und davon könnte man sogar noch einiges weglassen. mfg Torsten
@Moby AVR Was machst du eigentlich in einem C++ Thread? Widme dich lieber diesem hier "C versus Assembler->Performance". Dort kannst du bei dem Wettstreit endlich die Überlegenheit von ASM demonstrieren. Also wo bleibst du? Oder kannst du doch nur hohle Phrasen wiederholen?
Torsten R. schrieb: > Das ist immer so das Problem mit Vergleichen. Vielleicht so: C++ bietet einen ganzen Fuhrpark an Fahrzeugen. Dieser ist etwas umfangreicher als der Fuhrpark, der von C zur Verfügung gestellt wird. Wenn ich nur Brötchen holen will, lasse ich den Lieferwagen stehen, und nehm das Fahrrad. Nur dass das C++ Fahrrad schön Bunt ist und eine bessere Gangschaltung als das C-Fahrrad hat. Nur weil im Fuhrpark auch ein 50-Tonnen-Panzer steht, zwingt mich niemand den durch die enge Gasse zu fahren. Wenn ich das trotzdem tue, bin ich selber schuld, wenn ich steckenbleibe.
@ Karl Heinz > versteh ich nicht. > Was hat jetzt die andere Controller-Architektur mit C++ zu tun? > Die einzig relevante Frage lautet: gibt es dafür einen C++ Compiler - ja > oder nein? > Und dieselbe Frage stellt sich auch bei einem C Compiler. Aus Originalpost ergab sich die Frage, ob man einen Controller auswählen sollte, für den es einen C++-Compiler gibt, oder ob man den Controller nach anderen Kriterien auswählt und dann evtl eine andere Sprache (in diesem Fall C) erlernen muss. Ich würde nicht von Controller A zu Controller B wechseln, nur weil es für B einen C++-Compiler gibt. > Punkt ist doch: wenn ich nicht will, dann muss ich > Teile davon nicht nutzen. Auch für C++ gilt: You don't pay for what you > don't use. Natürlich nicht. Aber was bringt Dir dann C++, wenn Du im Endeffekt nicht viel davon nutzen kannst. Ich will hier nicht den x-ten C vs. C++ Flamewar anzetteln. Ich benutze beides und finde C++ als Sprache viel effizienter. Aber da ich auf einem Controller nur Teile davon sinnvoll nutzen kann, würde ich die Entscheidung für einen Controller nicht davon abhängig machen. > Ah. Nein. > COde wird da überhaupt nicht kopiert. Kommt drauf an: Auf Multicore-Systemen mit lokalen Speichern evtl schon, wenn Du den Linker anweist, für bestimmte Objekte den lokalen Speicher anstelle des Shared memory zu verwenden. Aber im allgemeinen ist das nicht der Fall, da hast Du recht. > Der springende Punkt > ist, dass du für eine komplizierte Initialisierung in C genauso den > enstprechenden COde aufrufen musst. Du wirst mir zustimmen, dass das Handling komplexer dynamischer Objekte in C++ wesentlich einfacher ist als in C. Wenn ich also eine Anwendnung habe, die mit vielen solchen Objekten arbeitet, dann geht das mit C++ viel einfacher. Bei den meisten MCU-Anwendungen ist das nicht der Fall, daher kann dieser Vorteil von C++ nicht genutzt werden. Das ist der springende Punkt.
Planlos schrieb: > Torsten R. schrieb: >> Das ist immer so das Problem mit Vergleichen. > > Vielleicht so: > > C++ bietet einen ganzen Fuhrpark an Fahrzeugen. Dieser ist etwas > umfangreicher als der Fuhrpark, der von C zur Verfügung gestellt wird. Ja, das ist schön ;-) Mit einem Vergleich kann man sagen, was man möchte und weicht dabei der Diskussion mit Argumenten aus. Es sagt viel mehr darüber aus, wie jemand denkt als das es irgend etwas beweisen / belegen würde. Wenn ich einem Laien etwas verständlich machen möchte, dann taugen sie ganz gut aber für eine Diskussion unter Kollegen erschließt sich mir der Sinn nicht.
schlappohr schrieb: > @ Karl Heinz > >> versteh ich nicht. >> Was hat jetzt die andere Controller-Architektur mit C++ zu tun? >> Die einzig relevante Frage lautet: gibt es dafür einen C++ Compiler - ja >> oder nein? >> Und dieselbe Frage stellt sich auch bei einem C Compiler. > > Aus Originalpost ergab sich die Frage, ob man einen Controller auswählen > sollte, für den es einen C++-Compiler gibt, oder ob man den Controller > nach anderen Kriterien auswählt und dann evtl eine andere Sprache (in > diesem Fall C) erlernen muss. Ich würde nicht von Controller A zu > Controller B wechseln, nur weil es für B einen C++-Compiler gibt. Ah. OK Da hab ich dann wohl im Laufe des Threads den Faden verloren. Ja. Unter dem Gesichtspunkt stimme ich zu.
schlappohr schrieb: > Natürlich nicht. Aber was bringt Dir dann C++, wenn Du im Endeffekt > nicht viel davon nutzen kannst. TriHexagon schrieb: >>> - keine implizite Konvertierung von void* >>> - namespaces >>> - templates >>> - überladende Funktionen >>> - Operatoren für eigene Typen >>> - typesichere enums >>> - //-Kommentare >>> - constexpr >>> - Konstruktoren / Destruktoren >>> - umfangreichere Standardlibraries: >>> - crc >>> - random number generators >>> - algorithmen (Suchen, Sortieren, Permutieren...) >> >> - Möglichkeit der Datenkapselung mit private und protected (ja, ich >> weiss, man kann sie umgehen) und inline Gettern/Settern -> kein runtime >> Penalty und trotzdem kann ich wilden Zugriffen auf Variblen einen Riegel >> vorschieben. > > - static_assert Alle statisch nutzbar auf einem µC. Und das sind hier längst nicht alle.
schlappohr schrieb: > Ich würde nicht von Controller A zu > Controller B wechseln, nur weil es für B einen C++-Compiler gibt. Da werden dir die Meisten auch zustimmen. Aber nicht C++ zu brauchen, da man nicht alle features benötigt, die die Sprache bietet, ist dann doch "etwas" engstirnig. Aber wir haben jetzt einen C/C++ Krieg hier, Kicad diskussion da, fehlt nurnoch der Troll im A&B Forum und der Freitag ist perfekt :-)
Operator S. schrieb: > fehlt nurnoch der Troll im A&B Forum und der Freitag ist perfekt :-) Ist doch schon da: Beitrag "Wie steige ich bei einem Hochkaräter ein?"
Operator S. schrieb: > Da werden dir die Meisten auch zustimmen. Aber nicht C++ zu brauchen, da > man nicht alle features benötigt, die die Sprache bietet, ist dann doch > "etwas" engstirnig. Sehe ich auch. C++ auf einem AVR geht wunderbar, man muss die Sprache aber können und wissen was man macht, das ist hier der Punkt. Und so wie der TO schreibt, ist er davon noch etwas entfernt.
@Viele, ohne Sortierung > Zwingt dich jemand dazu alle zu nutzen? Heißt das also, wenn ich nicht > alle Features von C nutze, soll ich doch lieber die Finger davon lassen? Nein. Es heißt, dass Du besser keine Zeit verschwenden sollst mit der Suche nach einem C++-Compiler, wenn Du schon einen C- Compiler hast, der das tut, was Du willst. > Das ist falsch und leider immernoch ein sehr verbreitetes Vorurteil. > Ineffizienter Maschinencode wird durch ineffiziente Programmierung > hervorgerufen, nicht durch die Sprache. Respekt, Du hast gerade ganz Compilerbau-Vorlesungen ausgehebelt. Übersetze ein Programm mit drei verschieden Compilern und Du bekommst drei verschiedene Binaries (außer bei Hello World vielleicht). Es gibt tausend Arten wie Du ein Programm übersetzen kannst. Und das gilt schon für Compiler derselben Sprache. Und die Unterschiede in den Ergebnissen wirken sich umso mehr aus, je kleiner die Zielarchitektur ist. >> Für einen Hobbybastler mag das vielleicht keine >> Rolle spielen. > Uhhh, Faul! Ich arbeite beruflich und privat mit Controllern und treffe privat auch andere Entscheidungen. Deswegen diese Bemerkung. Sorry, wenn ich jemandem auf die Füße getreten habe. > Nur weil im Fuhrpark auch ein 50-Tonnen-Panzer steht, zwingt mich > niemand den durch die enge Gasse zu fahren. Wenn ich das trotzdem tue, > bin ich selber schuld, wenn ich steckenbleibe. Und Du würdest Dir einen Fuhrpark mit einem 50-Tonnen-Panzer anschaffen, obwohl Du nur Brötchen holen fähst und das Fahrrad schön bunt ist? Vor allem , wenn Du dafür erst noch ein eine Stadt ziehen musst? > Nett ist ein blödes Wort, wenn etwas aus dem Kontext gerissen wird. Hat Zitate sind immer ohne Kontext, und der Rest von Torvalds' Aussage ist im wesentlichen eine Begründung für den zitierten Satz. > auch nichts mit echtzeit zu tun gehabt, als er das sagte. Das habe ich im folgenden Satz auch geschrieben. Aber es zeigt deutlich, das C++ nicht so everybody's Darling ist, wie man manchmal meinen könnte. > Das ist tatsächlich schön, sagt es doch, dass man auch mit C++ schlecht > programmieren kann, aber im normalfall nicht ;-) Den interessanten Teil hast Du weggelassen: "The bad news is you have to understand the efficiency aspects of the C++ code you write.[...]" > Aber wir haben jetzt einen C/C++ Krieg hier, Nein, das haben wir nicht. Die Frage, ob ein bestimmter Compiler für einen bestimmten Zweck geignet ist, ist schon gerechtfertigt, und ich bin der Meinung, dass das hier trotz der gegensätzlichen Ansichten recht sachlich abläuft, im Vergleich zu anderen Foren. In diesem Sinne, ein schönes Wochenende an alle.
Hallo Johan, Diese Entscheidung ist relativ leicht, hol dir einen PIC oder AVR (Kannst ja eine Münze werfen, wenn du dir unschlüssig bist) und danach beginnst du mit C. Wenn du schon etwas C++ kannst sollte dir der Syntax von C keine Schwierigkeiten bereiten. C würde ich vor allem empfehlen, da es viel mehr Beispiele in C als C++ gibt. Da du noch ein Anfänger bist, kommt dir das sicher zu gute. Wenn du dann etwas Vertrauter mit dem uC-Welt bist kannst du immer noch auf C++ umsteigen.
schlappohr schrieb: > Ein Lieferwagen bietet viel mehr Platz, als man zum Brötchenholen > braucht. Auf die Gefahr hin, mich zu wiederholen: das hängt von der Menge der Brötchen ab. Verstehst Du das? > Ein C++-Compiler bietet viel mehr Funktionen, als man auf einer kleinen > MCU sinnvoll nutzen kann. Ein C++-Compiler bietet trotzdem etliche Funktionen, die man auf einer kleinen MCU sinnvoll nutzen kann. Und alleine diese Funktionen sind es, die seinen Einsatz sinnvoll machen. > Wenn ich als Projektleiter entscheiden soll, ob wir auf eine andere > Controller-Architektur umsteigen, die ein anderes Konzept hat, teurer > ist, Einarbeitung in eine neue Toolchain erfordert und am Ende dasselbe > leistet, und das nur weil jemand C++ toll findet, ja, dann verlange ich > eine Rechtfertigung. Wer redet hier von einer anderen Controller-Architektur in einem kommerziellen Setting? Der TO ist ein Hobbyist und fragt, ob er PICs mit C++ programmieren kann oder welche Alternative er hat, wenn er in C++ programmieren möchte. Und da ist AVR eine gute Alternative, nicht zuletzt weil die Hardware sogar eigens für die Verwendung mit einer Hochsprache konzipiert und optimiert worden ist. > <Luftschnapp>. OOP ist wesentlich mehr als ein Sprachkonzept. C++ > Compiler erzeugen anderen Maschinencode und haben eine massiv komplexere > Speicherverwaltung. Sie haben ein komplizierteres Runtimesystem Tatsächlich erzeugt der avr-g++ haargenau denselben Maschinencode wie der avr-gcc, wenn man beiden Compilern äquivalenten C- bzw. C++-Quellcode vorsetzt. Keine Spur von einem "komplexen Runtimesystem" oder einem "ineffizienteren Maschinencode". Klassen, Methoden, Konstruktoren und Templates: davon findest Du am Ende im Assembler-Zwischencode genau gar nichts mehr, das optimiert der Compiler einfach weg. Töfte, wa? Probiers doch einfach mal aus, anstatt hier irgendwelchen Quatsch zu erzählen. Ich habs gemacht und durch Analyse des Assembler-Zwischencodes und der Maschinencodes festgestellt, daß die Unterschiede marginal bis nicht vorhanden sind und in einigen Fällen der C++-Compiler sogar einen minimal kleineren Maschinencode erzeugt. > Ich rede nicht von Assembler-Inlining. Ich rede davon, dass Code, der > dynamisch zur Laufzeit Objekte erzeugt, ein Zeitverhalten hat, das weit > schwieriger vorherzusagen ist. Dieser Einwand ist an Irrelevanz kaum zu überbieten, weil dynamische Allokation und die Notwendigkeit der Initialisierung von Speicher rein überhaupt gar nichts mit OOP zu tun hat. > Das ist jetzt aber nicht Dein Ernst, oder? malloc reserviert Speicher, > das ist im wesentlichen ein Eintrag in eine Tabelle, mehr nicht. Der > Aufruf eines Konstruktors legt Datenstrukturen an, kopiert Code falls > notwendig und ruft Initialiserungsfunktionen und weitere Konstrktoren > auf. Je nach Art der Klasse ist das geringfügig komplizierter, stimmst > Du mir da zu? Nein. Weil es Unfug ist, was Du schreibst. Der new-Operator in C++ ist im Prinzip nichts anderes als:
1 | void *operator new(size_t size) { |
2 | return malloc(size); |
3 | }
|
Ob mein Konstruktor Datenfelder initialisiert, Initialisierungsfunktionen oder weitere Konstruktoren aufruft, ist dem Programmierer überlassen. Das kann man natürlich machen, aber wenn man eine Datenstruktur in C erzeugt -- ganz gleichgültig, ob dynamisch oder nicht -- dann muß die genauso wie in C++ initialisiert werden. Ob ich den dazu notwendigen Code nun in einen C++-Konstruktor packe oder als C-Funktion aufrufe, ist überhaupt keinerlei Unterschied. > Und jetzt erklär mir mal bitte, > warum Du unbedingt einen Compiler verwenden willst, der dynamische > Objekte unterstützt, obwohl Du die nie brauchst. Oder Exceptions. Oder > dynamische Typprüfung. Will ich gar nicht, das ist nur eine Unterstellung Deinerseits. Ich könnte auf Mikrocontrollern auch prima mit einem C++-Compiler leben, der keines dieser Features hat. Keines dieser Features macht C++ aus, und demzufolge hat der avr-g++ standardmäßig nichtmal eine Implementierung für new() und delete() bzw. deren Placement-Pendants. Man kann das selbst nachrüsten, wenn man es denn braucht, aber auf Mikrocontrollern hat das nur in den allerwenigsten Situationen einen Nutzen. Manchmal, ganz selten, aber eben doch, beispielsweise wenn man mehrere komplexe Datenstrukturen verarbeiten muß, für die der verfügbare Speicher nicht ausreicht. Dann muß man entweder einen größeren Controller nehmen, oder die Datenstrukturen dynamisch erzeugen und zerstören -- mit malloc() in C oder mit new() in C++, das spielt keine Rolle, und ist auch intern haargenau dasselbe. Wie gesagt: probier's einfach aus. > Wenn Du einen Compiler hast, der das alles kann, > ok. Aber warum Du die Entscheidung für einen Prozessortyp davon abhängig > machen willst, kann ich nicht nachvollziehen. Weil der Compiler immer noch genügend viele Vorteile bietet, wenn man auf Features verzichtet, die auf einem Mikrocontroller meist überflüssig sind. Niemand zwingt einen alle Features von C++ zu benutzen, aber selbst wenn man nur den für Mikrocontroller sinnvollen Teil benutzt, gibt es mehr als genug Gründe dafür. Eine Kettensäge hat Vorteile gegenüber einer Handsäge, und Du versuchst uns hier zu verklickern, daß man zum Entasten von gefällten Bäumen lieber eine Handsäge benutzen sollte, weil so eine Kettensäge ja schließlich auch beim Fällen von Bäumen Vorteile hat. Atme bitte mal tief durch, ja?
Moby A. schrieb: > Deshalb: Klären: Was brauch ich wirklich ?!!! Um eine vernünftige Antwort auf diese Frage zu finden, müßte man doch erst einmal die zur Verfügung stehenden Möglichkeiten und ihre Vor- und Nachteile kennen. Bei Deiner tiefen, immer wieder gebetsmühlenartig vorgetragenen Abneigung gegenüber Hochsprachen können wir wohl davon ausgehen, daß Du die Möglichkeiten und Fähigkeiten von Hochsprachen nicht kennst und schon aus diesem Grunde nichts zur Diskussion beitragen kannst.
TriHexagon schrieb: > Das kompliziertere Runtimesystem rührt aber von Exceptions und RTTI her > und nicht OOP. Schalte Exceptions und RTTI aus, dann hast du die > gleichen Bedingungen wie unter C. Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal ausschalten. Im Artikel "C++" (https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch.
Vergleichende Beispiele könnten die Diskussion konkretisieren und Interessierten eine Einstieg in C++ bieten. Die verfügbare Literatur für Embedded C++ ist mir zwei bis drei Nummern zu kompliziert. Mcucpp ist für mich nachvollziebar. Leider nicht kommentiert. Das zwingt aber die Sache ganau zu studieren. So lernt man auch, Schritt für Schritt... Ich für mich werde den Weg mit C++ weitergehen, auch wenns öfters schwierig ist...
schlappohr schrieb: > Aus Originalpost ergab sich die Frage, ob man einen Controller auswählen > sollte, für den es einen C++-Compiler gibt, oder ob man den Controller > nach anderen Kriterien auswählt und dann evtl eine andere Sprache (in > diesem Fall C) erlernen muss. Ich würde nicht von Controller A zu > Controller B wechseln, nur weil es für B einen C++-Compiler gibt. Aus dem Originalpost ergibt sich aber, daß es nicht um einen Wechsel von einem auf einen anderen Controller geht, sondern zunächst einmal um die Auswahl eines Mikrocontrollers. Und da der TO bereits C++ beherrscht, C jedoch nicht, ist es sinnvoller für ihn, AVRs zu benutzen, weil dafür mit dem avr-g++ ein ausgereifter, freier C++-Compiler verfügbar ist.
schlappohr schrieb: >> Punkt ist doch: wenn ich nicht will, dann muss ich >> Teile davon nicht nutzen. Auch für C++ gilt: You don't pay for what you >> don't use. > > Natürlich nicht. Aber was bringt Dir dann C++, wenn Du im Endeffekt > nicht viel davon nutzen kannst. Weil das, was Du nutzen kannst -- Datenkapselung, Vererbung, Templates, Überladen von Funktionen, Methoden und Operatoren etc. -- alleine schon mehr als genug Vorteile bietet, die eindeutig für C++ sprechen. Daß C++ noch andere Features hat, die im Mikrocontroller-Bereich nicht sinnvoll eingesetzt werden können, spricht nicht dagegen, C++ zu benutzen, sondern nur dagegen, diese Features zu benutzen. > Kommt drauf an: Auf Multicore-Systemen mit lokalen Speichern Es geht hier immer noch um Mikrocontroller, oder? > Du wirst mir zustimmen, dass das Handling komplexer dynamischer Objekte > in C++ wesentlich einfacher ist als in C. Wenn ich also eine Anwendnung > habe, die mit vielen solchen Objekten arbeitet, dann geht das mit C++ > viel einfacher. Bei den meisten MCU-Anwendungen ist das nicht der Fall, > daher kann dieser Vorteil von C++ nicht genutzt werden. Das ist der > springende Punkt. Das Problem an diesem Punkt ist, daß er nicht nur springend, sondern vollkommen irrelevant ist. Die Frage ist letztlich immer nur, ob man dynamischen Speicher braucht oder nicht. Wenn man dynamischen Speicher braucht, geht es mit C++ viel einfacher. wie Du schon erkannt hast -- und trotzdem kostet das in C++ am Ende nicht mehr als in C, weil der Assembler- und Maschinencode für die Allokation und die Initialisierung am Ende genau dieselben sind. Trotzdem C++ hier also mehr Komfort bietet, erzeugt es am Ende überhaupt gar keinen Overhead. Ist doch prima: mehr Komfort ohne die geringsten Nachteile, findest Du nicht? Wenn man keinen dynamischen Speicher braucht, tun sich C und C++ wieder nichts, außer daß C++ viele komfortable Möglichkeiten bietet, die C eben leider nicht hat. Auch dabei kostet der zusätzliche Komfort überhaupt gar nichts: mehr Komfort ohne die geringsten Nachteile eben. Was spricht da also noch für C? Richtig: nichts. Nicht einmal ein bereits vorhandener Haufen C-Code, denn der läßt sich ja weiterhin auch unter C++ benutzen oder mit üblicherweise minimalem Aufwand portieren. Das Einzige, was ansonsten noch für C sprechen könnte, wäre, wenn man einen Haufen von Ignoranten und / oder Ideologen in seiner Entwicklungsabteilung sitzen hat, die jede Neuerung ablehnen. Aber das ist kein technisches, sondern primär ein soziales und sekundär ein Führungsproblem.
Sheeva P. schrieb: Ich stimme dir in praktisch allem zu. Nur das hier > Und da der TO bereits C++ beherrscht Lese ich das Originalposting > Ich habe aus privatem Interesse heraus auch etwas Erfahrung mit > C++ (Variablen, Datentypen, Schleifen, Funktionen, Strukturen, Zeiger). dann ist 'C++ beherrschen' wohl etwas weit hergeholt. Wenn er den hier von ihm angegebenen Sprachraum von C++ tatsächlich beherrscht, dann sind wir sowieso eher bei C als bei C++.
Viele der Anwesenden scheinen ein äußerst nebulöses Bild von C++ (und auch von OOP im allgemeinen) zu haben (und auch von anderen Themen aus dem unbekannten bedrohlichen Land hinter dem Tellerrand) und assoziieren die ungeheuerlichsten Dinge und Schreckgespenster damit, feuerspuckende Drachen, menschenfressende Konstruktoren, Handbücher mit mehr als 100 Seiten, etc. Ich musste mehrmals laut lachen beim Lesen.
Sheeva P. schrieb: > TriHexagon schrieb: >> Das kompliziertere Runtimesystem rührt aber von Exceptions und RTTI her >> und nicht OOP. Schalte Exceptions und RTTI aus, dann hast du die >> gleichen Bedingungen wie unter C. > > Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal > ausschalten. Im Artikel "C++" > (https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite > wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und > nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise > sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch. Ah das hab ich mir schon gedacht, hab ich aber nie nachgeprüft. Danke.
Sheeva P. schrieb: > Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal > ausschalten. Im Artikel "C++" > (https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite > wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und > nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise > sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch. Gibts dazu irgendwelche weiteren Infos wie das funktioniert? Zumindest der neuste (5.2) arm-g++ macht das nicht und der generierte Code ist ohne "-fno-exceptions -fno-rtti" einmal mal 60% größer (60KB vs. 38KB).
sebi707 schrieb: > Sheeva P. schrieb: >> Wenn man RTTI und Exceptions nicht benutzt, muß man sie nicht einmal >> ausschalten. Im Artikel "C++" >> (https://www.mikrocontroller.net/articles/C%2B%2B) hier auf der Seite >> wird zwar empfohlen, mit "-fno-exceptions -fno-rtti" zu übersetzen und >> nicht den avr-g++, sondern den avr-gcc zu benutzen, aber diese Hinweise >> sind zumindest für aktuelle Versionen von avr-g++ definitiv falsch. > > Gibts dazu irgendwelche weiteren Infos wie das funktioniert? Zumindest > der neuste (5.2) arm-g++ macht das nicht und der generierte Code ist > ohne "-fno-exceptions -fno-rtti" einmal mal 60% größer (60KB vs. 38KB). Bei mir wird immer mit -Os und -flto optimiert und zuletzt mit avr-strip die Symbole entfernt. Wie bist Du zu Deinem Ergebnis gekommen?
>> der neuste (5.2) arm-g++ macht das nicht und der generierte Code ist >> ohne "-fno-exceptions -fno-rtti" einmal mal 60% größer (60KB vs. 38KB). > Bei mir wird immer mit -Os und -flto optimiert und zuletzt mit > avr-strip die Symbole entfernt. Wie bist Du zu Deinem Ergebnis gekommen? arm-gcc, nicht avr-gcc! Ist es nicht so, daß der avr-gcc gar keine Exceptions und keine RTTI unterstützt? arm-gcc hat diese beiden Dinge sicher mit dabei, weshalb das Abschalten dieser sich auch bemerkbar macht.
Moby schrieb im Beitrag #4260564: >> Cortex-Mx Controller. Die Controller sind kaum komplexer als die >> gängigen 8Bit Mikrocontroller ... > > Da lachen ja (schon) die Hühner ;-) Wieso? Diese Aussage ist doch korrekt? Sie mögen wohl intern mehr und kleinere Transistoren haben und mehr verschiedene Peripherie auf dem selben Chip anbieten (die man nutzen kann wenn man sie braucht oder ignorieren wenn nicht) aber die jeweils im konkreten Projekt zu verwendende Peripherie lässt sich auch kein bisschen anders oder gar komplizierter handhaben (und nur darauf kommt es an) als beispielsweise bei nem AVR: Jedes einzelne Peripheriegerät hat vielleicht ein halbes Dutzend Register und ein eigenes Kapitel im Handbuch in dem alles schön erklärt ist, genauso wie auch schon zu 8-Bit Zeiten, und die Funktionsweise von beispielsweise einem 6-Kanal Timer auf nem Kinetis zu verstehen und zwei Kanäle davon in Betrieb zu nehmen (und die anderen 4 identisch aufgebauten einfach links liegen zu lassen) dauert auch keine Sekunde länger als beispielsweise die von einem 2-Kanal Timer auf nem AVR, in dem konkreten Fall übrigens eher sogar eher weniger weil logischer aufgebaut und nicht so verkrampft verknotet wie die 2 Kanäle auf nem AVR-Timer. Du kannst mir zum Beispiel nicht erzählen daß Du zwar einerseits fähig bist beispielsweise auf nem Atmega den ADC von einem Timer triggern zu lassen und nach der Wandlung einen Interrupt auszulösen imstande bist indem Du ein halbes Dutzend Bits in einer Handvoll Register entsprechend konfigurierst, so wie Du es aus dem Handbuch durch Lesen gelernt hast, jedoch das grundlegend selbe Vorhaben auf einem vergleichbar kleinen ARM-Controller als irgendwie komplizierter empfindest obwohl da ebenfalls nur eine Handvoll Bits in einer Handvoll Registern zu setzen sind, Register und Bits deren Namen einem sogar schon irgendwie seltsam vertraut vorkommen sollten und (o Wunder) im Wesentlichen die vergleichbaren Funktionen haben wie bei der anderen Architektur die Du vorher verwendet hast, das kannst Du mir nicht erzählen. Es ist nämlich kein bisschen komplizierter, es ist der exakt selbe alte Kram in grün statt blau. Kein Unterschied. Du kannst es übrigens auch in asm machen wenn Du unbedingt willst, auch das macht keinen Unterschied.
Moby A. schrieb im Beitrag #4261484: > TriHexagon schrieb: >> Die Qual der Wahl > > ...fällt zum Beispiel von Automobil-Steuergerätesoftware ganz eindeutig > zugunsten von prozeduralem C aus. In vielen Embedded-Bereichen schauts > ähnlich aus. Und was spricht konkret gegen prozedurales C++? Ich sehe da keinen Nachteil, sondern sogar Vorteile wie z.B. Typsicherheit (verhindert Fehler), typsichere Konstanten, static_assert um Fehler/Probleme zur compilezeit zu entdecken, etc.. Gerade bei "Automobil-Steuergerätesoftware" ist Sicherheit doch sehr wichtig, da helfen die eben genannten Features. Ich kann mir vorstellen, dass da ein paar Klassen der Sicherheit zuträglich sein könnte, da man mit Klassen Daten kapseln und vor unbefugten Zugriff schützen kann.
Da fällt mir gerade ein, gab es vor einem Jahr nicht Werbung von BMW als Arbeitgeber? Ich kann mich nicht mehr erinnern um welche Software es ging, aber auf jeden Fall um Softwareentwicklung bei BMW. Kann gut sein, dass es besagte Auto-Steuerungssoftware war (Fahrerassistenzsysteme?). Auf jeden Fall war der gezeigte Code in C++. TriHexagon schrieb: > da man mit Klassen Daten kapseln und vor > unbefugten Zugriff schützen kann. Nicht nur das, es macht die Überprüfung der übergebenen Daten auch leichter (da zentral).
TriHexagon schrieb: > "Automobil-Steuergerätesoftware" ist Sicherheit doch sehr wichtig, da > helfen die eben genannten Features. ... und werden dort trotzdem nicht in nennenswertem Umfang eingesetzt. Warum? Vielleicht hilft ein Zitat aus der Wikipedia: "Das breite Leistungsspektrum und die vielfältigen Gestaltungsmöglichkeiten der Sprache sowie die Bibliotheken führen zu verhältnismäßig langen Einarbeitungszeiten. Im Vergleich mit C bietet C++ eine enorme Fülle an Sprachmitteln." Ich würde daraus folgende Schlüsse ziehen: -> Es gibt nicht genügend qualifizierte Entwickler -> Die durchschnittliche C++ Software könnte besser sein Sprachen mit weniger Sprachmitteln tun es offensichtlich genauso. Je vielfältiger die Gestaltungsmöglichkeiten, desto schwieriger fällt es den Überblick zu behalten. Vielfältige Sprachmittel wollen richtig angewendet werden, sonst produzieren sie nur vielfältig suboptimalen Code. Nicht die Theorie vielfältiger Gestaltungsmöglichkeiten entscheidet, sondern die reale Praxis ihrer Umsetzung.
Bernd K. schrieb: > Du kannst mir zum Beispiel nicht erzählen daß Du zwar einerseits fähig > bist beispielsweise auf nem Atmega den ADC von einem Timer triggern zu > lassen [...] jedoch das grundlegend selbe Vorhaben auf einem vergleichbar > kleinen ARM-Controller als irgendwie komplizierter empfindest [...] Sagen wir's mal so ... auf einem AVR den ganzen Standardkram (bis hin zu parallel Primzahlen ausrechnen, LEDs blinken, Knöpfe registrieren und eine Melodie spielen) habe ich relativ schnell hinbekommen. Die Hardware-PWM auf einem SAM3X stellt mich aber nach wie vor vor größere Probleme. Nach meinem Dafürhalten (und ich sehe mich auch auf den Teilen nicht mehr als totalen Grünschnabel) habe ich die paar Bits korrekt gesetzt, es funktioniert trotzdem nicht. (Auf dem STM32 lief es wieder relativ zügig; aber dank Befehl von oben sind die Teile out.) > Es ist nämlich kein bisschen komplizierter, es ist der exakt selbe alte > Kram in grün statt blau. Kein Unterschied. Du kannst es übrigens auch in > asm machen wenn Du unbedingt willst, auch das macht keinen Unterschied. Einspruch, euer Ehren. Dieses ganze "ARM ist nicht schwerer als AVR"-Gerede ist großer Unfug und das wisst ihr selbst. Das fängt damit an, dass die klassische AVR-Toolchain einfach "tut", und die klassische ARM-Toolchain ohne eigenen Startup-Code nicht. Und es hört noch lange nicht damit auf, dass ein AVR-Datenblatt alle wesentlichen Bestandteile enthält, ein ARM-Datenblatt in der Regel aber nicht. Das ist der Komplexität und der Mächtigkeit der 32-Bitter geschuldet. Ein AVR hat keinen nennenswerten Clock-Tree; ein STM32 oder SAM3X schon. Obwohl das mit ein bisschen Einarbeitung alles nicht unmöglich ist, es bleibt schwerer, als in die AVR-Welt einzutauchen. Punkt. Und komme mir nicht mit IDEs wie Keil oder Arduino. Die verstecken die Magie auch nur, und wenn du mal einen zu neuen Chip bekommst oder deine eigene Hardware aufbaust, stehst du trotzdem erstmal im Regen.
S. R. schrieb: > Und komme mir nicht mit IDEs wie Keil oder Arduino. Die verstecken die > Magie auch nur, und wenn du mal einen zu neuen Chip bekommst oder deine > eigene Hardware aufbaust, stehst du trotzdem erstmal im Regen. So ist es beim AVR auch. Hier wird der Startup-Code auch dazu gelinkt. Oder was glaubst du wer die C-Laufzeitumgebung initialisiert und die main()-Methode aufruft? Seit Winavr relativ tot ist gibts nur noch die Tools von Atmel selbst. Und es interessiert auch niemanden warum was wie geht. Wenn du es einfach haben willst, dann nimm halt die IDE die dir der Hersteller empfiehlt und oft wie Sauerbier anpreist. Arduino und Keil in einen Topf zu werfen grenzt wirklich fast an Blödheit. S. R. schrieb: > und wenn du mal einen zu neuen Chip bekommst Wenn er aus der selben Linie kommt ist das sicher kein Problem. Wenn es etwas völlig anderes ist, dann wird das ganze wohl ähnlich ablaufen als wenn du versuchst einen PIC mit dem Atmel-Studio programmieren. Es wäre sicher besser die ganzen Nörgler setzen sich mal 2 Tage hin und versuchen die Zusammenhänge zu verstehen. Das ist besser angelegte Zeit als hier die Threads mit Unwissen, Falschaussagen und Gespenstern voll zu müllen.
Moby A. schrieb: > TriHexagon schrieb: >> "Automobil-Steuergerätesoftware" ist Sicherheit doch sehr wichtig, da >> helfen die eben genannten Features. > > ... und werden dort trotzdem nicht in nennenswertem Umfang eingesetzt. Noch. Darum gibt es sogar schon einen Codingstandard dafür: MisraC++:2008. > Ich würde daraus folgende Schlüsse ziehen: > -> Es gibt nicht genügend qualifizierte Entwickler Viele Embedded-Entwickler sind noch mit C unterwegs; das liegt einerseits an derselben Vorurteilen, die Du hier so gerne behauptest, aber auf der anderen Seite natürlich auch daran, daß C++ und C++-Werkzeuge erst in den letzten Jahren so ausgereift wurden, wie sie es heute sind. Daher ist es nur noch eine Frage der Zeit, bis sich die Vorteile von C++ auch im Embedded-Umfeld in der Breite durchsetzen werden. Wer das nicht mitgehen will, sollte sich rechtzeitig nach einem neuen Job umschauen, sofern er nicht bereits kurz vor der Rente steht. > -> Die durchschnittliche C++ Software könnte besser sein Dank höherer Typsicherheit, besserer Codeorganisation und einer besseren Wiederverwendbarkeit kann in C++ stabilere, komplexere, besser getestete und besser wartbare Software mit geringerem Aufwand umgesetzt werden. Da ist die Prognose, daß sich diese Vorteile durchsetzen werden, sicherlich nicht überraschend. Das ist übrigens ähnlich mit Deinem Assembler: das wird heutzutage in der Industrie kaum mehr benutzt, weil das außer in wenigen Randgebieten kaum noch Vorteile gegenüber C hat, dafür aber viel höhere Entwicklungskosten bedingt.
S. R. schrieb: > Einspruch, euer Ehren. Dieses ganze "ARM ist nicht schwerer als > AVR"-Gerede ist großer Unfug und das wisst ihr selbst. Ich finde es gibt ein paar Anfangsschwierigkeiten, danach ist es im Endeffekt irgendwie doch dasselbe wie beim AVR. S. R. schrieb: > Das fängt damit > an, dass die klassische AVR-Toolchain einfach "tut", und die klassische > ARM-Toolchain ohne eigenen Startup-Code nicht. Ja das stimmt, aber bei STM (keine Ahnung wie es bei den anderen ist) ist fertiges Linkerscript und Startupcode verfügbar. Das heißt man muss nur lernen es einzubinden. Wenn man ein mal gelernt hat wie es geht, ist es kein Problem mehr. Die meisten benutzen sowieso eine IDE, da geht das vollautomatisch. Beim AVR benutzen ja auch viele das AVR Studio. Ich persönlich benutze lieber Toolchain + Makefile + QtCreator auf Linux. S. R. schrieb: > Und es hört noch lange > nicht damit auf, dass ein AVR-Datenblatt alle wesentlichen Bestandteile > enthält, ein ARM-Datenblatt in der Regel aber nicht. Es gibt das Datasheet, Reference- und Programmingmanual. Das Datasheet brauche ich kaum, nur zum Herausfinden an welchen Bus die Peripherie hängt, welche Pins zu benutzen sind und welche Nummer die alternate function hat (um den Multiplexer einzustellen, da man sich oft aussuchen kann, welche Funktion welcher Pin übernehmen soll). In dem Referencemanual ist die Peripherie und deren Register genau beschrieben, so wie man es vom AVR kennt. Das Programmingmanual beinhaltet das Instructionset und die Beschreibung des ARM Kerns (ARM Cortex-Mx). Das braucht man kaum (das schaut man sich eher einmal an und gut ist), höchstens wenn man den NVIC direkt ansteuern will etc.. Ist aber sehr interessant, vor allem für jemanden der ein OS schreiben will, dann ist das die erste Anlaufstelle. S. R. schrieb: > Das ist der > Komplexität und der Mächtigkeit der 32-Bitter geschuldet. Das ist nicht die Schuld von 32-Bit, die 32-Bitter die ich bisher getroffen habe, könnten einfach mehr als der 8-Bit AVR. Man könnte sicher einen minimalistischen 32-Bit µC bauen, aber bisher kenne ich niemanden der das versucht hat. S. R. schrieb: > Obwohl das mit ein bisschen Einarbeitung alles nicht unmöglich ist, es > bleibt schwerer, als in die AVR-Welt einzutauchen. Punkt. Ich gebe zu, dass es ein wenig schwerer ist. Aber überdramatisieren darf man das nicht.
TriHexagon schrieb: > S. R. schrieb: >> Das ist der >> Komplexität und der Mächtigkeit der 32-Bitter geschuldet. > > Das ist nicht die Schuld von 32-Bit, die 32-Bitter die ich bisher > getroffen habe, könnten einfach mehr als der 8-Bit AVR. Man könnte > sicher einen minimalistischen 32-Bit µC bauen, aber bisher kenne ich > niemanden der das versucht hat. Das habe ich vorherigen Post wohl falsch verstanden. Ja die höhere Komplexität kommt mit der höheren Mächtigkeit. Aber ich finde die Komplexität hält sich auch beim ARM ziemlich in Grenzen. Dazu kommt ja, dass es da Cortex-M0, M0+, M3, M4, M7 (neu) gibt. Die Mächtigkeit und die Komplexität nimmt nach rechts zu. Während man mit M4/M7 schon einen richtigen Rechner bauen kann (eigentlich fehlt nur eine MMU, eine MPU ist schon da), ist der M0 mit einem AVR besser zu vergleichen.
Mach dich krass - lies ein Buch: "Real-Time C++: Efficient Object-Oriented and Template Microcontroller Programming" - von Christopher Kormanyos http://www.amazon.de/Real-Time-Efficient-Object-Oriented-Microcontroller-Programming/dp/3642346871
:
Bearbeitet durch User
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.