Ich lese gelegentlich, dass 8-Bit MCUs nicht optimale Zielplattformen
für C++ Compiler seien, allerdings weiß ich nicht genau wieso. Frage:
welche Kriterien sollten demnach für den Einsatz von C++ erfüllt sein
und was macht den Unterschied aus (Anforderungen C++ vs. C)?
Graphical User schrieb:> allerdings weiß ich nicht genau wieso.
Ich auch nicht.
Ich programmiere meine AVRs in C++ und das geht sehr gut. Man kann in
C++ deutlich besser kapseln als in C (mit Klassen und Vererbung) und der
vom Compiler erzeugte Object-Code wird bei richtiger Anwendung auch
nicht schlechter.
"new" ist das größte Problem, äquivalent zu "malloc" in C.
Auf Systemen mit so wenig RAM ist der Overhead von malloc/new im
Allgemeinen inakzeptabel. Dazu kommt, dass Objekte häufig als Pointer
übergeben/verwaltet werden, was bei Klassen, die nur wenige Bytes
umfassen, zu weiterem Overhead führt. Es gibt noch mehr solcher
Beispiele.
Wenn man sich dessen bewusst ist und generell ein Verständnis dafür hat,
welches C++-Feature welche Ressourcen wie benutzt, dann ist C++ auch für
kleinste µCs geeignet. Man tappt halt leicht in Ressourcenfallen, gerade
was RAM-Nutzung angeht.
Der Hauptunterschied ist nur die andere Syntax.
In C++ ist es oftmals schwer zu erkennen, was ein Ausdruck macht und
welche Ressourcen er belegt. Man muß darauf vertrauen, daß es aus dem
Namen des Ausdrucks hervor geht.
Ansonsten kann man in C und in C++ auf dem MC effiziente oder
verschwenderische Programme schreiben.
Peter
Sam P. schrieb:> Wenn man sich dessen bewusst ist und generell ein Verständnis dafür hat,
Ja, das braucht es auf jeden Fall, aber sowohl in C++ als auch in C.
Man kann auch in C viel Quatsch machen, z.B.
1
voidirgendwas(void)
2
{
3
charbuffer[10000];// was versteh ich schon vom Stack???
Andi D. schrieb:> das problem sind die dinge wie "new" oder "malloc" .. das geht auf solch> kleinen platformen schief ..
Ab wie viel RAM lasst sich der Heap halbwegs vernünftig einsetzen?
Gibt's da Erfahrungswerte?
Manateemoo schrieb:> Ab wie viel RAM lasst sich der Heap halbwegs vernünftig einsetzen?
Das hat mit der RAM Größe nichts zu tun. Die Frage ist, warum kann die
Größe erst zur Laufzeit bestimmt werden?
Ein MC hat in der Regel keine Alternative, wenn malloc fehl schlägt.
Also muß er soviel RAM haben, wie maximal benötigt wird. Und dann kann
dieser bereits zur Compilezeit reserviert werden.
Peter
Manateemoo schrieb:> Ab wie viel RAM lasst sich der Heap halbwegs vernünftig einsetzen?> Gibt's da Erfahrungswerte?
Angenommen, Du hast 1kB RAM und zwei Funktionalitäten, die jeweils
600Bytes allokieren wollen. Dann mußt Du dafür sorgen, daß immer nur
eine arbeiten darf, während die andere warten muß. Jede mehr
Funktionalitäten dazu kommen, umso schwieriger wird es, das zu
beherrschen.
Mit statischer Speicherverwaltung hingegen kannst Du das gar nicht
verwirklichen, denn der Linker/Locater kann nicht 2x600Byte in 1kB
unterbringen. Er zwingt Dich, mehr Speicher einzusetzen. Dafür kannst Du
aber auch sicher sein, daß das immer und unter allen Umständen
funktionieren wird.
Klar kann man das verwirklichen: Man allokiert statisch 600 Byte und
beide Funktionen nutzen diesen Speicher. Natürlich darf nur jeweils eine
Funktion gleichzeitig damit arbeiten, aber das ist im dynamischen Fall
ja auch so.
Ein Problem hat man dagegen bei folgendem Szenario:
- Funktion 1 benötigt 599 Byte
- Funktion 2 benötigt 600 Byte
- Funktion 3 benötigt 100 Byte
Jede Funktion allokiert ihren Speicher dynamisch.
Jetzt läuft:
- Funktion 1: Bekommt Byte 0-598
- Funktion 3: Bekommt Byte 599-698
- Funktion 1: Gibt Byte 0-598 frei
- Funktion 2: Bekommt keinen Speicher mehr, weil keine 600 Byte am Stück
frei sind.
Obwohl Funktion 1 und Funktion 2 nicht gleichzeitig laufen, geht es
schief. Aus diesem Grund (Fragmentierung) vermeidet man auf
Mikrocontrollern normalerweise dynamische Speicherallokation.
Am ehesten kann man es imo noch machen, wenn die allokierten Häppchen
alle die gleiche Größe haben. Oder wenn man garantieren kann, dass immer
nur eine Funktion läuft, die dynamischen Speicher verwendet und sie ihn
am Ende komplett freigibt. Aber dann könnte sie genauso auf einem
gemeinsamen statischen Speicher arbeiten. In anderen Fällen wird der
Speicher mit hoher Wahrscheinlichkeit früher oder später zu sehr
fragmentiert sein und eine Anforderung schief gehen.
xfr schrieb:> Aus diesem Grund (Fragmentierung) vermeidet man auf> Mikrocontrollern normalerweise dynamische Speicherallokation.
Man verwendet natürlich normalerweise keinen dynamischen Speicher.
Das mit der Fragmentierung ist mir bewusst. Ich frage mich nur ab wann
Dynamischer Speicher sinnvoll funktioniert.
Ich denke eher an eine Cortex M3 mit ca. 1MB Ram und nicht an ein
8-Bitter mit 2k Ram.
Oder ist es ohne MMU (z.B. Virtueller Speicher) einfach nicht vernünftig
drin?
Stefan Helmert schrieb:> Aber der Compiler müsste doch die dynamische Verwaltung auf einen> statische Verwaltung abbilden können?
wie soll er denn das machen?
size_t x = lese_daten_von_irgendwo();
void* p = malloc( x );
woher soll er denn wissen wieviel platz ein einplanen soll?
Peter II schrieb:> woher soll er denn wissen wieviel platz ein einplanen soll?
Da der Speicher nach oben hin begrenzt ist, muss das Konzept ja schon
eine obere Grenze kennen, sonst würde auch bei dynamischer Verwaltung
der Speicher überlaufen. Und aus dieser Grenze, kann das ja gewonnen
werden.
Aber wenn man die Klassen schreibt und nicht "dynamisch" erzeugt, weil
der Syntax einfach brauchbarer ist als structs mit Funktionen zu
verheiraten?!
Also wenn man vor der Hauptschleife schon alle news getätigt hat, weil
man einfach nur etwas übersichtlicher Programmieren will?!
Natürlich muss man dabei selbst den Speicher mitzählen und sich
wahrscheinlich eine entsprechende größer ausfallende Tolleranz als in C
lassen.
Wieso soll das nicht gehen?
Zedd schrieb:> Aber wenn man die Klassen schreibt und nicht "dynamisch" erzeugt, weil>> der Syntax einfach brauchbarer ist als structs mit Funktionen zu>> verheiraten?!>> Also wenn man vor der Hauptschleife schon alle news getätigt hat, weil>> man einfach nur etwas übersichtlicher Programmieren will?!>>>> Natürlich muss man dabei selbst den Speicher mitzählen und sich>> wahrscheinlich eine entsprechende größer ausfallende Tolleranz als in C>> lassen.>> Wieso soll das nicht gehen?
Wozu soll man mit dem Knüppel was in Klassen prügeln ohne dass es
notwendig ist? Wenn man richtig C kann, dann kann man damit genauso
übersichtliche Programme schreiben.
C++ macht nur Sinn, wenn man von Objekten zur Laufzeit neue Instanzen
bilden kann bzw. muss. Das geht halt auf einem uC nicht sinnvoll und man
braucht für die meisten uC Anwendungen keine objektorientierten Ansätze.
> Aber wenn man die Klassen schreibt und nicht "dynamisch" erzeugt, weil> der Syntax einfach brauchbarer ist als structs mit Funktionen zu> verheiraten?!
Ja genau so ;-)
> Also wenn man vor der Hauptschleife schon alle news getätigt hat, weil> man einfach nur etwas übersichtlicher Programmieren will?!
Halt nicht mit "new", sondern statisch anlegen...
> Natürlich muss man dabei selbst den Speicher mitzählen und sich> wahrscheinlich eine entsprechende größer ausfallende Tolleranz als in C> lassen.> Wieso soll das nicht gehen?
GEHEN tut das alles - man kann malloc() auch auf einem Mikrocontroller
compilen/einsetzen - nur wird es je nach Anwendung wahrscheinlich
ziemlich schnell nicht mehr funktionieren, weil der Speicher zu
fragmentiert ist, und kein unfragmentierter Speicher mehr frei ist.
Steel schrieb:> Wozu soll man mit dem Knüppel was in Klassen prügeln ohne dass es> notwendig ist? Wenn man richtig C kann, dann kann man damit genauso> übersichtliche Programme schreiben.
Eben nicht, dank virtuellen Funktionen, Vererbung etc. kann man in C++
übersichtlicher & hübscher programmieren - und das ist dann auch
Fehler-sicherer, weil der Compiler das macht, und man nicht alles von
Hand basteln muss.
> C++ macht nur Sinn, wenn man von Objekten zur Laufzeit neue Instanzen> bilden kann bzw. muss.
Nein. Man kann die auch wunderbar statisch anlegen. Habe ich auf einem
µC-Projekt (STM32F407) gemacht und der Code ist wunderhübsch.
> Und man braucht für die meisten uC Anwendungen keine objektorientierten Ansätze.brauchen tut man das theoretisch nie, aber einfacher gehts so oft.
Falls man weiß was man tut.
Ein Vorteil von C++ auf Mikrocontrollern ist imo, dass man verschiedene
Implementierungen der gleichen Schnittstelle nebeneinander nutzen kann.
Das geht in C nur umständlich über Funktionspointer.
Daher hat man in C++ schon bessere Möglichkeiten, seine Module zu
kapseln und austauschbarer zu machen. Das volle Potenzial lässt sich
aber wie gesagt erst mit dynamischen Objekten nutzen, die man auf nem
Mikrocontroller normalerweise nicht hat und auch nicht braucht.
auch auf AVR kann C++ per Template/Overloading elegante Programme
bescheren.
Und Objekte über Pointer führt bei AVR zur kürzeren indizierten
Addressierung und damit kürzeren Programmen.
Ob C oder C++, wichtig ist daß man's kann!
Ich habe C++ auf kleinen TI-Controller gemacht (F2810).
Alle new's natürlich vor der Hauptschleife. Aber die Konstruktoren sehen
einfach sauber aus.
Dann hatte ich eine Basis SPI-Klasse, die an die einzelnen HW
Sensor-Klassen vererbt wurden.
Die Datenkapselung in C++ ist sauberer als in C.
Ich würde nie wieder auf nur C zurückgehen.
Steel schrieb:> Wozu soll man mit dem Knüppel was in Klassen prügeln ohne dass es> notwendig ist? Wenn man richtig C kann, dann kann man damit genauso> übersichtliche Programme schreiben.
Gegenfrage: Warum nimmt man nicht eine Sprache, die einem extra
Hilfsmittel für die Übersichtlichkeit an die Hand gibt?
Das dumme ist, dass C++ komplex ist. Sehr komplex. Man muss sich bewusst
beschränken. Aber dafür muss man dann nicht mehr alles "zu Fuß" machen.
Irgendwann bastelt man sich in C nämlich auch was objektorientiertes,
und dann wird C umständlich.
Beschränkt man sich auf die Kernfunktionen und geht sparsam mit "new" um
(bzw. verzichtet völlig), dann ist C++ übersichtlicher und kann sogar
effizienter sein als C, da der Compiler über Klassen und Sichtbarkeit
mehr Informationen bekommt, was wo wie verwendet werden kann. Geht man
falsch ran, dann ist es unverständlicher und lahmer Murks.
Und so nebenbei, bei den technischen Daten moderner µCs geht so einiges.
Die größeren haben zig kB RAM, da lohnt sich dynamische
Speicherverwaltung. Derzeit schreibe ich einen LISP-Interpreter für SoCs
ab 64k RAM, der sogar -schock- Garbage Collection hat!
xfr schrieb:> Warum dann überhaupt mit new? Man kann auch in C++ Objekte statisch> anlegen.
Sogar besser als in C, weil man über Templates Puffergrössen
parametrisieren kann ohne dynamisch allozieren zu müssen. In C ist das
weit weniger elegant. Wobei man Templates auch einsetzen kann, ohne
dabei den Code über Gebühr zu vervielfachen.
Allerdings hilft es, wenn man eine Vorstellung davon hat, was für Code
ungefähr hinter den C++ Features steht.
Und Finger weg von der C++ Standardbibliothek!
Sowas harmlos aussehendes wie
int i;
std::cout << "counter: " << i << std::endl;
haut Dir Ruck Zuck Dein Flash voll (wenn es auf Deinem Embedded-System
überhaupt unterstützt wird).
Oder ist auch nicht länger als printf, wenn für embeded implementiert
und nicht einfach von den RAM-Milliardären übernommen. Bei Gelegenheit
muß ich doch mal was posten...
A. K. schrieb:> Sogar besser als in C, weil man über Templates Puffergrössen> parametrisieren kann ohne dynamisch allozieren zu müssen.
Ich bitte um ein Beispiel, das klingt etwas exotisch...
> In C ist das weit weniger elegant. Wobei man Templates auch einsetzen> kann, ohne dabei den Code über Gebühr zu vervielfachen.
Jede Verwendung wird vom Compiler für diese Objekt speziell impementiert
-> der code verdoppelt sich. Entscheidend aber ist die
Wiederverwendbarkeit des getesteten! source codes.
Auf einige Punkte möchte man nicht mehr verzichten. Vererbung,
Überschreiben, Slicing, verwendung von Referenzen und Konstruktoren,
eine eigene template Lib. und natürlich eine vernüftige Heap-verwaltung
> -> der code verdoppelt sich. Entscheidend aber ist die> Wiederverwendbarkeit des getesteten! source codes.
Der Code für die Methoden muss eigentlich nicht verdoppelt werden.
Lediglich die Attribute braucht jedes Object neu.
UARTc<0,64,64>uart0;// UART Kanal 0, 64/64 Bytes Puffer
2
UARTc<1,256,16>uart1;// UART Kanal 1, 256/16 Bytes Puffer
> Jede Verwendung wird vom Compiler für diese Objekt speziell impementiert> -> der code verdoppelt sich.
Yep, aber im obigen Beispiel ist das Template ein Wrapper um eine
normale Basisklasse, in der fast der gesamte Code steckt.
Interrupt-Handler inklusive. Im Template steckt kaum Code, weshalb sich
sehr wenig verdoppelt.
Das Template wird hier nur benötigt, um die besagten Puffer anzulegen
und den kanalspezifischen Interrupt-Handler auf den generischen Handler
durchzureichen.
> natürlich eine vernüftige Heap-verwaltung
Der Witz in diesem Beispiel ist, dass dafür kein Heap gebraucht wird.
Mal zur Info wie malloc und free typischerweise implementiert wird:
Speicher: Nehmen wir mal an, das wären 8 Bit Worte und wir hätten einen
8 Bit Adressbereich, damit wird das übersichtlicher. Wir haben einen
String ABCD in einem Speicherbereich der mit Malloc alloziert wurde und
ab Adresse 236 beginnt
234: #??? Zeiger zum vorherigen Datenblock
235: #243 Zeiger zum nächsten Datenblock
236: A
237: B
238: C
239: D
240: #0
241: #236 Zeiger zum vorherigen Datenblock
242: #??? Zeiger zum nächsten Datenblock
243: ???? Daten des nächsten Datenblocks
Man hat also eine doppelt verkettete Liste. Wohin jetzt die Zeiger genau
zeigen ist implementationsabhängig. Ebenso wie denn ein freier Block
gekennzeichnet wird. Bei einem free wird einfach der Block auf "frei"
gesetzt, und gegebenenfalls mit freien Blöcken vorher und nachher
vereinigt. Und natürlich hat man in der Regel keine 8-Bit Pointer
sondern mindestens 15 Bit. (16Bit-1Bit für Kennung ob frei ist) Wie
schon gesagt, das ist nur, damit es übersichtlicher wird.
Was bei C++ noch an zusätzlichen Aufwand anfällt ist eine Tabelle mit
den virtuellen Methoden einer Klasse, damit Du die aufrufen kannst ohne
den Typ der Klasse genau wissen zu müssen. Ich bin kein Freund von C++,
viele der Sachen kriegst Du auch einfacher mit einfacheren Sprachen hin.
Christian Berger schrieb:> Was bei C++ noch an zusätzlichen Aufwand anfällt ist eine Tabelle mit> den virtuellen Methoden einer Klasse, damit Du die aufrufen kannst ohne> den Typ der Klasse genau wissen zu müssen.
Das fällt nur an, wenn virtuelle Methoden verwendet werden. Und der
Aufwand dafür ist nicht wesentlich grösser, als der, den man für eine
analoge Implementierung in C reinsteckt.
Ohne virtuelle Methoden und bei abgeschalteter RTTI entsteht kein
Zusatzaufwand gegenüber C.
> Ich bin kein Freund von C++,> viele der Sachen kriegst Du auch einfacher mit einfacheren Sprachen hin.
Jedem Tierchen sein Pläsierchen. Ich empfinde C++ zwar auch nicht als
wirklich gelungenen Entwurf, kann darin aber einiges einfacher und vor
allem leichter wiederverwendbar und übersichtlicher gestalten als in C.
Andere Leute mögen das anders sehen.
wow,
ich muss gestehen von den Interna was und wie da wo in C oder C++ landet
hab ich keinen blassen aber ich progge einfach gern in C++ ... ist halt
mein Pläsierchen :-D es geht auf jeden Fall auf dem 8-bitter wie auf
32-bittern
wobei C++ wie es mir scheint dann doch ein bisschen hungriger nach FLASH
und RAM ist aber es hält sich in Grenzen und die Vorteile wiegen das
meiner Meinung nach auf.
guckst du hier: http://www.avr-cpp.de und http://www.mySTM32.de
meine lieblings Tutorials >>*schäm*<<
Gruß J.
Moin,
ne Menge Leute haben sich nu die Finger fransig getippt, aber keiner hat
bisher erwähnt, dass C++ keinen richtigen API-Standard besitzt. Im
Gegensatz zu C. Sprich: Die Symbol-Dekorationen ("mangling") macht jeder
C++-Compiler anders. Einen Quasi-Standard hat man nur mit GCC.
Deswegen gilt bei grösseren Projekten in meiner Umgebung immer noch:
- Libraries, und Kernels werden in C geschrieben
- GUIs, grössere Userspace-Programme in C++ und Python
Klar kann man über eine C++-Lib einen C-API layer setzen, aber die
Library ist damit noch nicht "sauber". Es gibt ne Menge bekannter
Gründe, dass Kernels wie Linux niemals in C++ geschrieben sind. Bei
einigen Compilern ist es ziemlich mühsam, den C++-Ballast, den man nicht
haben will, abzuspecken, da kann man sie gleich sauber in C schreiben.
Mit einem grossen Fragezeichen ist immer noch behaftet, ob sich C++
amortisiert (hat). Für mich persönlich geht's mit in C handcodierten
"Objektklassen" und entsprechenden Python-Wrappern immer noch am
stabilsten und läuft auch noch auf einem uC. (Anmerkung: bin schon seit
20 Jahren mit C++ "dabei"). Im Gegensatz zu Python verletzt C++ einige
"keep it simple"-Prinzipien und verleitet Anfänger, ne Menge falsch zu
machen.
Letztendlich soll jeder so machen, wie er am besten zum Ziel kommt, nur
gibt es schon genannte Aspekte zur Kollaborative und nicht zuletzt in
der Industrie auch zur Code-Verifikation und -Zertifizierung.
Grüsse,
- Strubi
>aber keiner hat>bisher erwähnt, dass C++ keinen richtigen API-Standard besitzt.
Ich muss gestehen, dass ich deine Aussage nicht verstehe. Kannst Du mal
ein konkretes Beispiel machen?
Gerd E. schrieb:> Sowas harmlos aussehendes wie>> int i;> std::cout << "counter: " << i << std::endl;>> haut Dir Ruck Zuck Dein Flash voll (wenn es auf Deinem Embedded-System> überhaupt unterstützt wird).EmbededC++ schrieb:> Oder ist auch nicht länger als printf, wenn für embeded implementiert> und nicht einfach von den RAM-Milliardären übernommen.
Eine minimalistische Implementation, die noch ein paar im Hintergrund
ablaufende Dinge wie die Locales weglässt, wäre meiner Meingung nach
sogar deutlich sparsamer als printf, da die Ausgaben ja alle über
entsprechende separate Operator-<<-Implementationen gemacht wird. Der
wesentliche Vorteil: Bei printf muß der Ausgabecode für alle
unterstützen Datentypen mit gelinkt werden, auch für die, die im
Programm gar nicht genutzt werden. Deshalb gibt es beim AVR ja auch als
Krücke die verschiedenen printf-Varianten, wo man per
Linker-Kommandozeile zwischen verschiedenen Kompromissen wählen muß.
Dazu kommt bei printf allgemein noch die Notwendigkeit für den
Format-String-Parser.
Bei cout dagegen gibt's für jeden Datentyp eine separate Funktion, die
einfachen Typen können auch gleich inline abgefrühstückt werden. Dadurch
wird der Code kleiner, und man kann automatisiert dafür sorgen, daß
wirklich nur genau die Konvertierungen im Programm landen, die auch
benutzt werden. Und ich wüßte auch nicht, warum das langsamer sein
sollte. Da kein Formatstring geparst werden muß, dürfte es eher
schneller sein.
A. K. schrieb:> xfr schrieb:>> Warum dann überhaupt mit new? Man kann auch in C++ Objekte statisch>> anlegen.>> Sogar besser als in C, weil man über Templates Puffergrössen> parametrisieren kann ohne dynamisch allozieren zu müssen. In C ist das> weit weniger elegant.
Wie meinst du das? Bei deiner Beschreibung denke ich an sowas:
1
uint8_tbuffer[BUF_SIZE];
Aber du scheinst noch was anderes zu meinen.
A. K. schrieb:> Christian Berger schrieb:>> Was bei C++ noch an zusätzlichen Aufwand anfällt ist eine Tabelle mit>> den virtuellen Methoden einer Klasse, damit Du die aufrufen kannst ohne>> den Typ der Klasse genau wissen zu müssen.>> Das fällt nur an, wenn virtuelle Methoden verwendet werden. Und der> Aufwand dafür ist nicht wesentlich grösser, als der, den man für eine> analoge Implementierung in C reinsteckt.
Allerdings landen die Tabellen beim avr-g++ leider unnötigerweise im
RAM. Oder hat sich das inzwischen geändert?
Strubi schrieb:> ne Menge Leute haben sich nu die Finger fransig getippt, aber keiner hat> bisher erwähnt, dass C++ keinen richtigen API-Standard besitzt. Im> Gegensatz zu C.> Sprich: Die Symbol-Dekorationen ("mangling") macht jeder> C++-Compiler anders. Einen Quasi-Standard hat man nur mit GCC.
Du meinst nicht API, sondern ABI. Das stimmt zwar, aber nun erzeugt man
auf einem kleinen µC selten Programme, bei denen Teile des Code mit
unterschiedlichen C++-Compilern übersetzt wurden und zusammengelinkt
werden müssen.
Und daß es in C einen Standard gäbe, stimmt auch nicht. Es gibt auch
nicht nur name-mangling, sondern auch noch einige weitere Dinge, wie
z.B. Parameterübergabe oder die Größen der Integer- und Float-Typen.
Übrigens gibt es z.B. unter Windows auch für C mehrere verschiedene
Varianten von name-mangling.
> Klar kann man über eine C++-Lib einen C-API layer setzen, aber die> Library ist damit noch nicht "sauber". Es gibt ne Menge bekannter> Gründe, dass Kernels wie Linux niemals in C++ geschrieben sind.
Nunja, wenn ich mir die Gründe ansehe, die Linus Torvalds so nennt, sind
die eher an den Haaren herbeigezogen und zeugen eher davon, daß er sich
entweder erst gar nicht richtig mit C++ beschäftigt hat und daher auch
keine Ahnung davon hat oder es einfach nur nicht mag.
Zwischen Kernels und Userspace-Programmen ist sowieso nochmal das
Systemcall-Interface, so daß man da auch in C noch entsprechende Wrapper
hat. Und was die Compilierbarkeit mit verschiedenen Compilern angeht,
ist gerade Linux da ein interessantes Beispiel, da Linus ja keinen Hehl
draus macht, daß er den Kernel ausschließlich für gcc schreibt und für
nix anderes, da er sehr regen Gebrauch von gcc-Erweiterungen macht.
Intel hat meines Wissens mal mit erheblichem Aufwand seinen Compiler
Linux-Kernel-kompatibel gemacht. Ob er das heute auch noch ist, weiß ich
aber niht.
Rolf Magnus schrieb:> Wie meinst du das? Bei deiner Beschreibung denke ich an sowas:
Klar geht das so. Aber das kann man nicht im Treiber selber machen, wenn
parametrisierbare Grössen oder meherere Instanzen (z.B. mehrere UARTs)
möglich sein sollen. Daher muss das entweder dynamisch alloziert werden,
oder der Caller tut es selbst und übergibt den Puffer an die Instanz des
Treibers.
Beitrag "Re: C++ für Embedded: ab welchen Prozessormerkmalen?"
Rolf Magnus schrieb:> Allerdings landen die Tabellen beim avr-g++ leider unnötigerweise im> RAM. Oder hat sich das inzwischen geändert?
Das ist nun eher eine Frage der konkreten Implementierung als der
Sprache. Ausserdem geht es hier nicht um riesige Datenmengen. Ich dürfte
auch unter C++ Anhängern einen gewissen Konsens geben, dass man solche
Konzepte nicht bei einem ATtiny10 verwendet. Aber bei einem ATmega32
fällt das nicht mehr gross auf.
A. K. schrieb:> Rolf Magnus schrieb:>> Wie meinst du das? Bei deiner Beschreibung denke ich an sowas:>> Klar geht das so. Aber das kann man nicht im Treiber selber machen, wenn> parametrisierbare Grössen oder meherere Instanzen (z.B. mehrere UARTs)> möglich sein sollen. Daher muss das entweder dynamisch alloziert werden,> oder der Caller tut es selbst und übergibt den Puffer an die Instanz des> Treibers.
Gut, aber die Verwendung von Templates ändert doch daran nichts.
Doch. Die Arrays sind Teil des Templates, nicht des Anwendungsprogramms.
Die Anwendung gibt ans Template die gewünschten Puffergrössen mit und
die Puffer sind Teil der Instanz. Ist die Instanz statisch, dann auch
die Puffer. Das Template wiederum ist Teil des Treibers, nicht der
Anwendung.
Man kann so etwas auch weiter generalisieren. Ich hatte es hier bewusst
weggelassen, aber das kann auch so aussehen:
1
template<intno,intrxsz,inttxsz>
2
...
3
GBuffer<uint8_t,rxsz>rxb;
4
GBuffer<uint8_t,txsz>txb;
5
...
6
};
In diesem Fall ist GBuffer<> ein generisches Template für den Umgang mit
sequentiellen Puffern in Verbindung mit Treibern mit Interrupt-Handlern.
Braucht man ja öfter mal, nicht nur bei UARTs.
>> Daher muss das entweder dynamisch alloziert werden,>> oder der Caller tut es selbst und übergibt den Puffer an die Instanz des>> Treibers.>> Gut, aber die Verwendung von Templates ändert doch daran nichts.
Die Organisation ist anders. In A.K. s Beispiel hat zb der
Anwendungsprogrammierer keine Chance die Klasse über Puffergrößen
'anzulügen'. Wieder eine potentielle Fehlerquelle weniger.
Letzen Endes kann keine Programmiersprache zaubern. Alles was man in
jeder x-beliebigen Programmiersprache machen kann, kann man auch in
Assembler machen. Höhere Programmiersprachen haben einfach nur den Sinn,
von dieser Ebene wegzuabstrahieren und den Focus mehr auf
Softwaretechnik zu legen.
> Was bei C++ noch an zusätzlichen Aufwand anfällt ist eine Tabelle> mit den virtuellen Methoden einer Klasse, damit Du die aufrufen> kannst ohne den Typ der Klasse genau wissen zu müssen.
Schon richtig.
Aber was ist die Alternative?
elends lange switch-case Orgien, die über eine Typ Kennung in die
jeweilige Funktionalität verzweigen. Und wehe du vergisst bei der
nächsten Programm-Erweiterung auf die Ergänzung eines einzigen
switch-case auf die neu eingeführte Typkennung.
Wenn man solche Vergleiche macht, dann darf man nicht nur fragen "Was
kostet mich das in der Sprache X" sondern man muss sich auch fragen "Und
wie mach ich das in meiner Programmiersprache". Dann merkt man nämlich
sehr schnell, dass viele C++ Konzepte gar nicht dumm sind, IM VERGLEICH
zu der Variante, wie man dasselbe in reinem C erreichen würde. Die
Zusatz-Kosten sind überschaubar (wenn überhaupt) und der Gewinn kann
beträchtlich sein. 'Kann', muss nicht. Denn der C Weg steht einem ja in
C++ immer noch offen.
Man kann ALLES was man in C++ machen kann (oder in jeder anderen
Programmiersprache) auch in C machen (oder in Assembler). Das ist nicht
die Frage. Die Frage ist: mit welchem Aufwand; mit welchem
Fehlerpotential; mit welchen Möglichkeiten einer Programmorganisation,
so dass man das Programm auch in 15 Jahren noch warten und erweitern
kann ohne dass gleich alles auseinander fällt. Und da hat C++ gegenüber
C nun mal die Nase vorn.
A. K. schrieb:> Yep, aber im obigen Beispiel ist das Template ein Wrapper um eine> normale Basisklasse, in der fast der gesamte Code steckt.> Interrupt-Handler inklusive. Im Template steckt kaum Code, weshalb sich> sehr wenig verdoppelt.
Das mit den Interrupts würde mich mal interessieren, wie das in C++
geht.
Ich hätte gedacht, daß ich für die 4 UARTs (ATmega2560) auch 8
Interrupthandler benötige (USART0_RX .. USART3_RX, USART0_UDRE ..
USART3_UDRE).
Kannst Du mal den kompletten Code zeigen?
Peter
Peter Dannegger schrieb:> Ich hätte gedacht, daß ich für die 4 UARTs (ATmega2560) auch 8> Interrupthandler benötige (USART0_RX .. USART3_RX, USART0_UDRE ..> USART3_UDRE).
Der obige Code war für LPC2000 und da gibts nur einen pro UART. Aber das
Prinzip ändert sich sich nicht sehr. Nur gibts dann eben pro Irq-Typ
einen Handler in der Basisklasse, also für RX und UDRE. Bei 4 Instanzen
der Klasse, eine pro UART, sind das dann auch wieder deine 8.
Wie sich das exakt ausformuliert hängt vom Interrupt-Controller und
dessen Einbindung in die Entwicklungsumgebung ab. Beim VIC der LPC2000
wird die Adresse des Handlers zur Laufzeit explizit zugewiesen, was die
Sache programmtechnisch deutlich vereinfacht. Hier steht also
sinnngemäss als Teil der Initialisierung im Template:
VicSetVector(..., UARTc<...>::irq);
Wes ich oben wegliess: Es gibt eine Verwaltungstabelle, die die
Kanalnummer in die Hardware-Adresse und in diesem Fall die Nummer des
Vektors umsetzt.
Bei anderen Interrupt-Einbindungen wie bei AVR oder CM3 mit fest
definierten Handler-Namen muss man anders vorgehen. Da kommt man nicht
drum herum, ausserhalb des Templates Stubs für alle Vektoren der Devices
vorzubelegen. Also jetzt mal unbeschadet der Namen und der exakten
Syntax wieder sinngemäss in aller Kürze:
extern "C" {
void UART0_RX_vector() _irq_ { UART::objp[0]->rx_handler(); }
void UART0_UDRE_vector() _irq_ { UART::objp[0]->udre_handler(); }
void UART1_RX_vector() _irq_ { UART::objp[1]->rx_handler(); }
...
}
Der Trick ist jedesmal, im Irq-Stub über dieses Array an die realen
Objekte ran zu kommen. In der Verwaltungstabelle stehen beim CM3
beispielsweise die pro Kanal erforderlichen Bits vom NVIC drin, die ja
auch gesteuert werden müssen (NB: da ist Bitbanding ganz nützlich).
@A. K.
Danke für die Antwort.
Ich muß zugeben, daß diese Frage auch mehr theoretischen Charakter
hatte.
Ich habe zwar alle 4 UARTs benutzt, aber auf völlig unterschiedliche
Weise:
1.UART:
- im SPI-Mode zum Keyboard (Tasten, Encoder, LEDs)
- arbeitet nur im Interrupt und frischt die Bits für Keypress und
Encoder auf
2.UART:
- im SPI-Mode als Erweiterungsbus (ADCs, DACs, 74HC595 usw.)
3.UART
- UART zum PC (2 normale FIFOs)
4.UART
- UART zum eDIPTFT43-A (SMALL PROTOKOLL)
Lange Rede, kurzer Sinn: Es ließe sich eh kein gemeinsamer Code nutzen.
Ich habe bei MC-Anwendungen den Eindruck, daß sich nur sehr selten ein
gemeinsamer Deckel über verschiedene Tasks stülpen läßt. Und das ist ja
bei C++ der Hauptpunkt.
Bzw. wenn mehrere Tasks gleich sind, geht das auch gut über Schleifen
oder Arrays.
Peter
Man kann alles was man in C++ kann auch in C machen.. irgendwie... nur
für "moderne" Design-Patterns ist C++ wesentlich eleganter.
Wenn ich mir Code-Reuse anschaue, ist C++ wesentlich besser geeignet, da
man eben schöner kapseln kann.
Ich habe in der Arbeit lange gebraucht, aber nun sind so ziemlich alle
überzeugt, dass C++ einfach schöneren Code ergibt.
und schöner Code ist zu 99% kleiner und schneller wie "hochoptimierter"
C-Code... Das ist leider Fakt und lässt sich in der Literatur seit Mitte
der 70er nachlesen.
C++ (und alle Highlevel-Sprachen - C++ ist sowas eigentlich nicht)
bietet halt dummerweise mehr Möglichkeiten schlechten Code zu
schreiben...
Dafür ist es strikter typisiert wie C und das ist meiner Einschätzung
nach im professionellen Umfeld der Hauptvorteil... char und void ist
eben nicht das selbe, auch wenn einem das C glauben lässt ;)
73
Das klingt ja alles wunderschön, allein mir fehlt der Zugang.
In C schreibe ich direkt hin, was ich gerade machen will.
In C++ muß ich immer erst zurück ins h-File und ne Klasse anlegen oder
erweitern. Und dann wieder an die Stelle, wo ich dann die Klasse
aufrufe.
Das wirkt auf mich nicht sonderlich effizient oder übersichtlich.
In C habe ich gelernt, alles was keinen Code erzeugt, kommt ins h-File.
Klassen erzeugen aber Code.
Aber sie müssen auch bekannt gemacht werden, also doch ins h-File.
Die Trennung zwischen Deklaration und Definition gilt also in C++ nicht
mehr.
Ist schon sehr kompliziert das mit dem C++.
Peter
Peter Dannegger schrieb:> Das klingt ja alles wunderschön, allein mir fehlt der Zugang.
Ich glaube, es ist die Richtung, aus der man auf seine Probleme kuckt.
Solange man noch auf die Bits im Statusregister sieht, geht man eher den
Weg Assembler -> C (== komfortabler Assembler). Bei Controllern, wo man
die höchstmögliche Leistung herausholen möchte, will man auch die
Kontrolle über den erzeugten Code behalten.
Bei komplexeren Problemen ist C++ sicherlich unvermeidlich; da
interessiert auch überhaupt nicht mehr, was im Statusregister des
Prozessors abläuft und wo sich physikalisch die GByte an RAM befinden.
Die Leute, die die aktuellen, neuen ICEs nicht zum Laufen bekommen,
kennen wohl auch keine Statusregister mehr :-)
Peter Dannegger schrieb:> In C habe ich gelernt, alles was keinen Code erzeugt, kommt ins h-File.
Das sollte man auch in C++ so machen.
> Klassen erzeugen aber Code.
Nein, nicht die Klassendeklaration im h-File. Und die Methodendefinitio-
nen stehen im cpp-File.
Man kann einen Methodenrumpf zwar auch direkt in die Klassendeklaration
schreiben, dann ist die Methode aber implizit als inline deklariert und
erzeugt deswegen ebenfalls keinen Code, zumindest nicht direkt. Code
wird in diesem Fall erst an der Stelle erzeugt, wo die Methode aufgeru-
fen wird, also in einem cpp-File.
Auch in C werden Inline-Funktionen, die in mehreren Modulen benötigt
werden, gerne in h-Files geschrieben.
> Die Trennung zwischen Deklaration und Definition gilt also in C++ nicht> mehr.
Doch, daran hat sich überhaupt nichts geändert.
> Ist schon sehr kompliziert das mit dem C++.
Es gibt sicher einige Dinge, die in C++ recht kompliziert und schwer zu
durchschauen sind. Die Regeln, was man ins h- und ins cpp-File schreibt,
gehören aber nicht dazu.
Peter Dannegger schrieb:> Das klingt ja alles wunderschön, allein mir fehlt der Zugang.>> In C schreibe ich direkt hin, was ich gerade machen will.>> In C++ muß ich immer erst zurück ins h-File und ne Klasse anlegen oder> erweitern. Und dann wieder an die Stelle, wo ich dann die Klasse> aufrufe.
Auch in C muss man Funktionen zuvor deklarieren, in C++ Funktionen &
Klassen. Wenn man die Klasse vorher nie verwendet, kann man die auch
komplett "inplace" an einer Stelle deklarieren & implementieren:
class UART {
void send (uint8_t byte) { UDR0 = byte; }
};
> Das wirkt auf mich nicht sonderlich effizient oder übersichtlich.
Eben doch - indem man Implementation von Deklaration trennt, kann man im
.h-File auf einen Blick alle Funktionen und Member-Variablen sehen, ohne
erst durch eine 2000 Zeilen lange Codedatei zu scrollen... Und damit das
Interface dieser Klasse, das was den Benutzer der Klasse interessiert.
> In C habe ich gelernt, alles was keinen Code erzeugt, kommt ins h-File.> Klassen erzeugen aber Code.
Nein. Nur die Funktionen der Klasse. Die Klasse an sich ist nur eine
"Hilfe" für den Compiler, ähnlich wie structs in C.
> Aber sie müssen auch bekannt gemacht werden, also doch ins h-File.> Die Trennung zwischen Deklaration und Definition gilt also in C++ nicht> mehr.
Wie oben gesagt, ist das sehr wohl so.
> Ist schon sehr kompliziert das mit dem C++.
Stimmt, aber es ist nunmal nicht jedes Programm ein LED-Blinker - für
komplexe Probleme können mächtigere Tools effizienter sein...!
Peter Dannegger schrieb:> ...> In C++ muß ich immer erst zurück ins h-File und ne Klasse anlegen oder> erweitern. Und dann wieder an die Stelle, wo ich dann die Klasse> aufrufe.
Hallo Peter, ich nehme an das du in C auch schon öfter Funktionen mit
vielen Parametern gehabt hast und diese an Unterfunktionen weiter
gegeben hast. Also was hast du gemacht ? Du hast dir Structs definiert
mit den Parametern darin und diese übergeben. Und schon hast du eine
(methodenlose) Klasse ohne es zu wissen gehabt und musstest ins h File
zum Ändern der Struktur;).
> Ist schon sehr kompliziert das mit dem C++.
Nö ;)
Yalu X. schrieb:> Nein, nicht die Klassendeklaration im h-File. Und die Methodendefinitio-> nen stehen im cpp-File.
So konsequent aber nur, wenn man Templates als systematischeren
Nachfolger von komplexen Präprozessor-Makros versteht.
Yalu X. schrieb:> Nein, nicht die Klassendeklaration im h-File. Und die Methodendefinitio-> nen stehen im cpp-File.
Na dann is ja gut.
Ich weiß jetzt auch nicht mehr, warum ich den Eindruck hatte, da stünde
Code drin. Muß mir mal die Beispiele gründlicher ansehen.
Peter
Peter Dannegger schrieb:> In C habe ich gelernt, alles was keinen Code erzeugt, kommt ins h-File.
Das machen manche so, ist aber total unsinnig. Ins h-File sollte das
gehören, was man benötigt, um das dazugehörige c-File von woanders
verwenden zu können. Also Funktionsdeklarationen, Typedefs und Defines,
die auch außerhalb des c-Files benötigt werden.
Alles, was nur innerhalb der c-Datei benötigt wird, also z.B. Prototypen
von statischen Funktionen und interne Defines gehören in die c-Datei.
> Klassen erzeugen aber Code.> Aber sie müssen auch bekannt gemacht werden, also doch ins h-File.> Die Trennung zwischen Deklaration und Definition gilt also in C++ nicht> mehr.
Eine Klassendeklaration ist das gleiche wie die Deklaration von Structs
oder Funktionensprototypen in C. Die Definition der Methoden (also der
Code) ist in der cpp-Datei, genau wie C.
Weniger schön ist imo nur, dass private Variablen und Methoden auch ins
h-File müssen. Das verletzt das Information-Hiding-Prinzip und lässt
sich afaik nur mit dynamischer Speicherallokierung (Factory-Methode)
bzw. virtuellen Methoden umgehen.
xfr schrieb:> Weniger schön ist imo nur, dass private Variablen und Methoden auch ins> h-File müssen. Das verletzt das Information-Hiding-Prinzip
Korrekt. Wobei aber genau ebendies eine Voraussetzung darstellt, dass
man mit auf klassischen einzelnen Quelltexten basierendem Quellcode und
individueller Übersetzung der Quellcode-Module sehr effizienten Code
erzeugen und mit statisch oder auf dem Stack allozierten Instanzen statt
nur im Heap arbeiten kann.
C++ ist ein stilistisch nicht allzu eleganter Kompromiss, keine saubere
Lösung. Aber immerhin liegt hier im Forum der Fokus auf
Mikrocontrollern, nicht auf Desktop-GUIs. Da sind Resourcenfragen
relevanter.
xfr schrieb:> Peter Dannegger schrieb:>> In C habe ich gelernt, alles was keinen Code erzeugt, kommt ins h-File.>> Das machen manche so, ist aber total unsinnig. Ins h-File sollte das> gehören, was man benötigt, um das dazugehörige c-File von woanders> verwenden zu können. Also Funktionsdeklarationen, Typedefs und Defines,> die auch außerhalb des c-Files benötigt werden.>
bei C++ templates findest du oft alles in einem einzigen h File. Ich
mags auch lieber getrennt.
@OT
"C++ in embedded systems: Myth and reality"
http://www.eetindia.co.in/ARTICLES/1998FEB/PDF/EEIOL_1998FEB02_EMS_TA.pdf
Peter Dannegger schrieb:> In C habe ich gelernt, alles was keinen Code erzeugt, kommt ins h-File.Hans-Georg Lehnard schrieb:> bei C++ templates findest du oft alles in einem einzigen h File. Ich> mags auch lieber getrennt.
Ist aber nur die Schablone. Das erzeugt immer noch keinen Code.
Hans-Georg Lehnard schrieb:> bei C++ templates findest du oft alles in einem einzigen h File. Ich> mags auch lieber getrennt.
Und wo wird bei Templates der Code erzeugt? - Richtig, bei der
Verwendung des Codes der Templates (oder der Klassen, die Templates
benutzen) im .cpp-File.
Aus heutiger Sicht muss man eigentlich das klassische Prinzip von
Quellcode-Texten in .h/.c aufgeben und Code in einer Art Datenbank
platzieren, aus der der Programmierer nur jene Information bezieht, die
er grad benötigt. Dann löst sich die Frage Interface/Implementierung in
Luft auf und von anderen Klassen als der grad bearbeiteten sieht man nur
das Interface.
Sowas gibts natürlich. Und auch basierend auf klassischem Quellcode gibt
es natürlich Programmierwerkzeuge, die ungefähr dieses Schema
implementieren. Aber die Frage ist, inwieweit dieses althergebrachte
Quellcode-Paradigma heute noch zeitgerecht ist. Zumal Compiler heute
gerne den eigentlichen Übersetzungsschritt dem Linker überlassen, weils
vorher nicht mehr wirklich gut geht.
Troll schrieb:> Und wo wird bei Templates der Code erzeugt? - Richtig, bei der> Verwendung des Codes der Templates (oder der Klassen, die Templates> benutzen) im .cpp-File.
Und wo wird bei heutigen Compilern jenseits der µC-Klasse der Code
erzeugt? Alles miteinander im Linker, jedenfalls wenn man das so will.
Der eigentliche Compiler liefert nur mehr vorgekauten Zwischencode ab.
Für Optimierung ist das sehr nützlich.
Nope, hier geht es um die Sicht auf den Quellcode. Nicht an welcher
Stelle des gesamten Übersetzungsprozesses der Compiler die
Maschinenbefehle erzeugt.
Troll schrieb:> Hans-Georg Lehnard schrieb:>> bei C++ templates findest du oft alles in einem einzigen h File. Ich>> mags auch lieber getrennt.>> Und wo wird bei Templates der Code erzeugt? - Richtig, bei der> Verwendung des Codes der Templates (oder der Klassen, die Templates> benutzen) im .cpp-File.
Für den Compiler machts keinen Unterschied ...
Mir ging es aber um das Lesen von Quellcodes für Menschen.
A. K. schrieb:> Nope, hier geht es um die Sicht auf den Quellcode. Nicht an welcher> Stelle des gesamten Übersetzungsprozesses der Compiler die> Maschinenbefehle erzeugt.
Dann sehe ich aber keinen prinzipiellen Unterschied zu C.
1
#define GROESSER(a,b) (a > b)
und
[c]template<T> bool Groesser(T a, T b) { return a > b; }
stehen beide im .h File und halten dort den entsprechenden Code.
Klar verleiten Template-Funktionen (gerade wegen der nicht Vorhandenen
Notwendigkeit, jede Zeile mit einem '\' abzuschließen) dazu, sie
umfangreicher zu gestalten, als C-Makros, aber letzendlich gab es diesen
Bruch in der Aufteilung Deklaration->.h und Code->.c(pp) aus
Programmierersicht ("Menschen", "Sicht auf den Quellcode") schon vor
C++.
Eben. Wie ich vorhin darlegte halte ich die Trennung in getrennten
Quellcode für Interface und Implementierung für mittlerweile veraltet.
Im Grunde reicht ein Quellcode für das ganze Modul, aus dem sich
Programmierumgebung und Compiler die für sie passenden Elemente
rauspicken. Zumal dort auch die Doku gut hinein passt.
Zur ursprünglichen Frage:
Für mich stellt sie sich gar nicht :)
Ob ich etwas lieber in C oder in C++ schreibe, hängt fast ausschließlich
von der Programmgröße ab. Alles, was maximal ein paartausend Zeilen lang
ist, habe ich in C schneller hingeschrieben. Eine Klassenstruktur spielt
ihre Vorteile erst bei größeren Programmen aus. Dann ist C++ die bessere
Wahl. Ein weiterer großer Vorteil von C++ sind die von der STL und den
Boost-Libraries zur Verfügung gestellten Highlevel-Datentypen, die das
Programmieren stark erleichtern.
Bei Steuerungsanwendungen (dazu gehören auch die meisten µC-Anwendungen)
ist zwar eine Strukturierung in Klassen möglich, meist stellt sich aber
heraus, dass von jeder Klasse nur maximal eine Instanz benötigt wird.
Solche Singletons kann man auch sehr gut in C realisieren, indem man je-
des in ein eigenes Programmmodul packt, wobei alle nur intern benötigten
Funktionen und globalen Variablen als static deklariert werden. Ob man
das so macht oder doch lieber C++ nimmt, ist dann eher Geschmackssache.
Die typischen 8-Bit-Controller sind meist so spärlich mit Flash und RAM
ausgestattet, dass darauf sowieso keine großen Programme Platz haben,
für die sich eine Klassenstruktur lohnen würde. Deswegen ist es mir
ziemlich egal, wie gut solche Plattformen von C++-Compilern unterstützt
werden.
Umgekehrt bieten embedded Plattformen, die für komplexere Software
geschaffen sind, ausreichend Ressourcen, um ohne nennenswerte Ein-
schränkungen auch C++ verwenden zu können.
Graphical User schrieb:> "C++ in embedded> systems: Myth and reality" werde ich lesen.
Scheint ja sehr einseitig zu sein:
"Anything C can do, C++ can do better"
Peter
Peter Dannegger schrieb:> Scheint ja sehr einseitig zu sein:> "Anything C can do, C++ can do better"
Eher so: C++ umfasst C vollständig, auch syntaktisch, mit wenigen
kleinen Unterschieden im Detail. Alles was C kann, kann also C++
mindestens genauso gut. Und manches geht in C++ eben besser.
A. K. schrieb:> Und manches geht in C++ besser.
Und wirklich gar nichts schlechter??
Wieso wurde dann reines C nicht schon lange abgeschafft??
Liegt es nur daran, dass viele Entwickler lieber C als C++
programmieren?
CS schrieb:> Und wirklich gar nichts schlechter??
Wie sollte das möglich sein, wenn C++ (nahezu) eine Obermenge von C ist?
Wenn also ein C Programm mit allenfalls kleinen Änderungen auch als C++
übersetzbar ist?
> Liegt es nur daran, dass viele Entwickler lieber C als C++> programmieren?
Nicht jeder Entwickler mag C++.
Nicht jeder Entwickler kann C++.
Die meisten Entwicklungsumgebungen für Mikrocontroller können kein C++.
Meist können sie es allenfalls dann, wenn drunter GCC werkelt.
A. K. schrieb:> Wie sollte das möglich sein, wenn C++ (nahezu) eine Obermenge von C ist?> Wenn also ein C Programm mit allenfalls kleinen Änderungen auch als C++> übersetzbar ist?
Das hoert sich hald so ein bisschen an wie "Jemand hat ein Auto
entwickelt, dass alles kann was ein normales Auto auch kann, nur dass es
kein Benzin braucht - trotzdem setzt es sich jahrelang nicht durch..."
Sorry, aber bin in C++ nicht so tief drin. Wenns so viel besser wäre,
dann würden ja alle Hersteller einen C++-Compiler dazuliefern - schon
aus Marketinggründen ("Schnellere Entwicklung", "mehr
wiederverwendbar"...)
Oder lieg ich da falsch???
Gibt es eine g++ Version eigentlich für AVR/ARM? Wäre interessant mal
damit ein wenig rumzuspielen bzw. Vergleichsprojekte zu machen...
Will keine Diskussion zu C vs C++, glaub das ist so sinnvoll wie über
Betriebssysteme zu diskutieren...
CS schrieb:> Oder lieg ich da falsch???
Ein leidlich fehlerarmer C++ Compiler ist ein ziemlich erkleckliches
Stück Arbeit. Sehr viel komplexer als C. Das macht ein Hersteller nur,
wenn er sich sicher ist, dass diese Arbeit nicht für die Katz ist.
Produkte setzten sich auch nicht automatisch durch, bloss weil sie
besser sind. Sondern:
1
- Entwickler verwenden C, weil es für µC Enwicklung kein C++ gibt.
2
- Die µC-Hersteller bieten kein C++, weil die Entwickler C gewöhnt sind.
3
- Entwickler verwenden immer noch C, weil die Hersteller immer noch kein C++ bieten. Oder zu wenige.
4
- Die µC-Hersteller bieten immer noch kein C++, weil die Entwickler immer noch C brauchen.
5
...
Das haben wir schon immer so gemacht, da könnte ja jeder kommen. ;-)
CS schrieb:> Gibt es eine g++ Version eigentlich für AVR/ARM? Wäre interessant mal> damit ein wenig rumzuspielen bzw. Vergleichsprojekte zu machen...
Ich bin nicht mit den aktuellen AVR-Entwicklungsumgebungen von Atmel
vertraut, nachdem Atmel da ja kräftig dran gedreht hat. Anno WinAVR war
das jedenfalls dabei und problemlos möglich.
Diverse Entwicklungsumgebungen für ARM basieren auf GCC. Mindestens
einige davon, wenn nicht vielleicht sogar alle, bieten daher auch C++.
Das Hauptfeature von C++ ist ja die objektorientierte Programmierung mit
Klassen, Vererbung usw. Da das nur mit dynamischem Speicher ordentlich
funktioniert, macht man das auf Mikrocontrollern in der Regel nicht.
Bleiben also "nur" die anderen, weniger bedeutenden Verbesserungen, mit
denen man seinen Code besser strukturieren kann. Aber nur dafür lohnt es
sich aus Herstellersicht nicht unbedingt, einen vollwertigen C++
Compiler zu entwickeln.
Ist vielleicht auch ein Henne-Ei-Problem. Man ist ja als professioneller
Entwickler daran interessiert, möglichst wiederverwendbaren Code zu
schreiben, der auf vielen Plattformen laufen kann. Da hat man mit reinem
C mit Abstand die besten Chancen. Was hilft mir mein Projekt in
wunderschönem, modularem C++, wenn ich meine Hardwareplattform umstellen
möchte und es für den neuen Mikrocontroller keinen C++ Compiler gibt.
Also bleibt man lieber bei C. Und weil alle bei C bleiben, sehen die
Hersteller nicht die Notwendigkeit, einen C++ Compiler anzubieten ...
CS schrieb:> Das hoert sich hald so ein bisschen an wie "Jemand hat ein Auto> entwickelt, dass alles kann was ein normales Auto auch kann, nur dass es> kein Benzin braucht - trotzdem setzt es sich jahrelang nicht durch..."
Könnte man so sagen. Denn diesas Auto wäre teurer als normale Autos
mitsamt der voraussichtlichen Benzinkosten. Jedenfalls aus Sicht des
Anbieters, der dafür viele viele Mannjahre Entwicklungsarbeit
reinstecken müsste.
Bei grossen Eisen lohnt sich C++ schon lange. Deshalb existiert auch C++
in GCC - und nur als Nebeneffekt davon auch C++ für Microcontroller.
xfr schrieb:> Ist vielleicht auch ein Henne-Ei-Problem
Ebendies spielt sicherlich eine wesentliche Rolle.
xfr schrieb:> Das Hauptfeature von C++ ist ja die objektorientierte Programmierung mit> Klassen, Vererbung usw. Da das nur mit dynamischem Speicher ordentlich> funktioniert, macht man das auf Mikrocontrollern in der Regel nicht.
Es funktioniert auch statisch, und deshalb geht es wunderbar und
problemlos auf µCs - bis runter in die 2k-Flash-Klasse.
CS schrieb:> Gibt es eine g++ Version eigentlich für AVR/ARM? Wäre interessant mal> damit ein wenig rumzuspielen bzw. Vergleichsprojekte zu machen...
GCC bietet C++ für AVR, ARM, MSP430, MIPS/PIC32, Renesas RX - vermutlich
für alles, wofür ein backend für die Zielplattform vorhanden ist.
Vergleiche habe ich einige durchgeführt. Es gibt keinen Grund, C++ nicht
einzusetzen. Die Mythen von "enormer Flash- und RAM-Bedarf" oder
"riesiger Startup-Code" stimmen nicht.
A. K. schrieb:> Ich bin nicht mit den aktuellen AVR-Entwicklungsumgebungen von Atmel> vertraut, nachdem Atmel da ja kräftig dran gedreht hat. Anno WinAVR war> das jedenfalls dabei und problemlos möglich.
Zu den IDEs kann ich auch nichts sagen, für die Kommandozeile
funktioniert
http://www.atmel.com/tools/ATMELAVRTOOLCHAINFORLINUX.aspx problemlos.
Hinter der 3.4 (Atmel-Version) verbirgt sich GCC 4.6.2
xfr schrieb:> Was hilft mir mein Projekt in> wunderschönem, modularem C++, wenn ich meine Hardwareplattform umstellen> möchte und es für den neuen Mikrocontroller keinen C++ Compiler gibt.
Welche neuen Mikrocontroller sind das, wofür es kein C++ oder GCC gibt?
Ist es nicht eher genau anders, nämlich dass für neue Architekturen der
Hersteller gleich auf GCC setzt, weil der Compilerbau ziemlich aufwändig
ist?
Yalu X. schrieb:> Ob ich etwas lieber in C oder in C++ schreibe, hängt fast ausschließlich> von der Programmgröße ab. Alles, was maximal ein paartausend Zeilen lang> ist, habe ich in C schneller hingeschrieben.
Wieso ist das in C schneller getippt?
Meine Erfahrung ist die, dass C++-Quelltexte kleiner sind :-)
Z. B. durch das implizite "this", Default-Werte für Funktionsparameter
und templates.
Die andere Frage ist: Ab wann ist ein Programm groß, und würde man beim
Erreichen dieser Grenze umstellen?
> Sorry, aber bin in C++ nicht so tief drin. Wenns so viel besser wäre,> dann würden ja alle Hersteller einen C++-Compiler dazuliefern - schon> aus Marketinggründen ("Schnellere Entwicklung", "mehr> wiederverwendbar"...)
Welcher ernstzunehmende Hersteller hat denn 2012 noch kein C++?
CS schrieb:> Wieso wurde dann reines C nicht schon lange abgeschafft??
Ganz einfach:
Weil C++ deutlich komplizierter ist als C - oder nennen wir es
'komplexer' (klingt besser).
Für Leute, die den ganzen Arbeitstag nix anderes machen als in C++
irgendwas zu programmieren, ist das alles kein Thema. Die haben nämlich
keine anderen Probleme, die ihnen im Kopf herumkollern.
Aber für Leute, die eben nicht nur 100% in C++ programmieren, sondern
z.B. auch Schaltungen entwickeln, Leiterplatten layouten, Gehäuse
konstruieren, mit Zulieferern herumfeilschen und ihren Kunden
Telefonseelsorge angedeihen lassen müssen, ist C++ schlichtweg
unbrauchbar, weil nicht zu merken. Ich merk sowas ja an mir selber, daß
ich versehentlich mal nen Pascal-Ausdruck in ne C-Quelle tippe oder nen
C-Ausdruck in Verilog oder umgekehrt. Man braucht ne Weile, um mental
umzupolen und bei C++ ist diese Weile viel zu lang.
Ich sehe die ganz gleiche Diskussion bei Leiterplattenleuten und
Konstrukteuren, wo manche auf besonders mächtige Tools schwören, dabei
aber vergessen, daß man selbige tagtäglich benutzen muß, um drin zu
bleiben. Früher hatte ich mal ganz flüssig mit Autocad konstruieren
können, heute muß ich erstmal nachgrübeln 'wie war das doch gleich mit
...'
Kurzum, sowas wie C++ geht in größeren Firmen, wo jeder seine
Monokultur/Spezialisierung betreiben kann. In kleineren Firmen - dem
sogenannten Mittelstand - geht es schwer oder garnicht, weil es da keine
ausreichend weit gehende Arbeitsteilung gibt und man als Ingenieur viel
mehr Probleme hat als bloß die Programmierung - und weil nur die
Wenigsten nen Kopf haben wie ein Elefant.
W.S.
Roland H. schrieb:> Yalu X. schrieb:>> Ob ich etwas lieber in C oder in C++ schreibe, hängt fast ausschließlich>> von der Programmgröße ab. Alles, was maximal ein paartausend Zeilen lang>> ist, habe ich in C schneller hingeschrieben.>> Wieso ist das in C schneller getippt?
Wenn man alle Funktionen als Methoden in Klassen packt, muss man jeden
Methodenkopf doppelt schreiben, einmal in der Klassendeklaration und
einmal in der Methodendefinition. In C gilt dies nur für diejenigen
Funktionen, die über Modulgrenzen hinweg verwendet werden, also
praktisch "public" sind. Jede Änderung der Methodenparameter muss man
ebenfalls an zwei Stellen vornehmen. Hinzu kommt der Rahmen der
Klassendeklaration selbst (also class { public: ... private: ...}). Bis
zu einem gewissen Grad nimmt einem ein leistungsfähiger Editor oder eine
IDE diese Arbeit ab. Trotzdem habe ich in C++ immer das Gefühl, einen
Großteil der Zeit redundanten Code zu tippen.
> Meine Erfahrung ist die, dass C++-Quelltexte kleiner sind :-)
Das sind sie auch, sobald man Dinge wie die STL nutzen kann/darf, aber
eben nur dann.
A. K. schrieb:> Produkte setzten sich auch nicht automatisch durch, bloss weil sie> besser sind. Sondern:> - Entwickler verwenden C, weil es für µC Enwicklung kein C++ gibt.> - Die µC-Hersteller bieten kein C++, weil die Entwickler C gewöhnt> sind.> - Entwickler verwenden immer noch C, weil die Hersteller immer noch> kein C++ bieten. Oder zu wenige.> - Die µC-Hersteller bieten immer noch kein C++, weil die Entwickler> immer noch C brauchen. ...
Oft würden die Entwickler gerne C++ verwenden, aber der Chef oder die
Firmenphilosophie schreiben C vor.
Nur um nochmal ein Statement in die Diskussion einzubringen, das
unabhängig von dem Prozessortyp oder anderen Randbedingungen ist:
C++ ist ein schlecht gestaltetes Amalgam aus verschiedenen
Programmiersprachenkonzepten, das mit Gewalt in eine C-artige
Erscheinungsform gepresst wurden.
Natürlich ist das bewusst zugespitzt formuliert, natürlich wird das
Widerspruch von den Leuten hervorrufen, die C++ tagtäglich freiwillig
verwenden. Aber C++ leidet an einer unglaublich überladenen (im
mehrfachen Wortsinne) Syntax und hat die Chance vertan, bei der
Gelegenheit mal mit dem Ballast von C aufzuräumen.
Ich habe viel Spaß gehabt, als ich mir die C++ FQA ("frequently
questioned answers", http://yosefk.com/c++fqa/ ) durchgelesen habe. In
der arbeitet sich der Autor an der C++ FAQ ab, deren Antworten er
paraphrasiert und dann im Detail ausführt, warum die Antwort
falsch/unvollständig ist oder die Probleme von C++ schönfärbt/ignoriert.
Das ist natürlich auch ein hochgradig subjektives Dokument, über das
sich auch an einigen Stellen diskutieren lässt, vielleicht an manchen
Stellen auch überholt ist. Aber es hat dennoch viele interessante Punkte
und ist generell spaßig zu lesen, wenn man sich für die Details von
Programmiersprachen interessiert. Eigentlich sollte sich jeder mal
http://yosefk.com/c++fqa/defective.html durchlesen. Selbst wenn man
nicht der Meinung des Autors ist gewinnt man doch mal eine Einsicht,
welche Kriterien man an Programmiersprachen anlegen kann.
Viele Grüße,
Simon
Roland H. schrieb:> xfr schrieb:>> Das Hauptfeature von C++ ist ja die objektorientierte Programmierung mit>> Klassen, Vererbung usw. Da das nur mit dynamischem Speicher ordentlich>> funktioniert, macht man das auf Mikrocontrollern in der Regel nicht.>> Es funktioniert auch statisch, und deshalb geht es wunderbar und> problemlos auf µCs - bis runter in die 2k-Flash-Klasse.
Das ist es eben, ich programiere schon seid vielen Jahren in C++
verwende wie selbstverständlich z.B. templates der STL für deren
Verwendung immer dyn. Speicher von einer heap-verwaltung alloziieren
wird. Wie kann ich dies an einen statischen Speicher binden?
> W.S. schrieb:> Für Leute, die den ganzen Arbeitstag nix anderes machen als in C++> irgendwas zu programmieren, ist das alles kein Thema. Die haben nämlich> keine anderen Probleme, die ihnen im Kopf herumkollern.
So ganz stimmt deine Argumentation nicht, die Verwendung von C++ futures
ist fliessend möglich. Die verwednung des C++ synt. kann ja auch nur
teilweise erfolgen, z.Z. nur Klassen anstatt struct Definitionen.
Deshalb muss ich kein C++ freak sein und meine Kenntnisse entwicken sich
schrittweise.
> W.S. schrieb:> Kurzum, sowas wie C++ geht in größeren Firmen, wo jeder seine> Monokultur/Spezialisierung betreiben kann. In kleineren Firmen - dem> sogenannten Mittelstand - geht es schwer oder garnicht, weil es da keine> ausreichend weit gehende Arbeitsteilung gibt und man als Ingenieur viel> mehr Probleme hat als bloß die Programmierung - und weil nur die> Wenigsten nen Kopf haben wie ein Elefant.
Gerade in einer kleineren Firmen ist deren verwendung ein entscheidener
Vorteil für das Produkt, wenn es, wie z.B. in meinen Fall, über viele
Jahre entwickelt und gepflegt werden muss. Ach ja und ich telefoniere
zwischen durch auch schon mal mit einigen Kunden...
> Oft würden die Entwickler gerne C++ verwenden, aber der Chef oder die> Firmenphilosophie schreiben C vor.
Ein ziemliches Armutszeugniss und die sichtweise des Management reicht
nur wochenweise bis zum Projektabschluss, Lieferung... push, money and
forget
oder der chef hat keine Ahnung... Mein chef ist Entwickler :-)
Simon Budig schrieb:> C++ ist ein schlecht gestaltetes Amalgam aus verschiedenen> Programmiersprachenkonzepten, das mit Gewalt in eine C-artige> Erscheinungsform gepresst wurden.
Völlig richtig. Mir standen stellenweise die Haare zu Berge als ich den
Stroustrup las. Der hat auf die syntaktischen Fehler von C noch weitere
drauf gesetzt, statt sie gerade zu ziehen.
Aber der Versuch des Pentagon, Ada durchzusetzen, ist an der Realität
gescheitert. Man hat faktisch eben nur C oder C++ zur Auswahl. Der Rest
spielt im Zusammenhang mit Microcontrollern keine nennenswerte Rolle.
Yalu X. schrieb:> Wenn man alle Funktionen als Methoden in Klassen packt, muss man jeden> Methodenkopf doppelt schreiben, einmal in der Klassendeklaration und> einmal in der Methodendefinition.
Nicht immer, es gilt nicht für die inline-Variante. Bei "public" ist der
Aufwand in C/C++ der gleiche, ebenso, wenn es einer forward-Deklaration
bedarf. Bleiben also non-inline private Methoden. OK.
Dem steht die Verwendung von "this" gegenüber, und das spart eine ganze
Menge Tipperei. Durch den Klassennamen spart man sich auch ggf. einen
Präfix für den Funktionsnamen, damit die Namen eindeutig sind.
> Hinzu kommt der Rahmen der> Klassendeklaration selbst (also class { public: ... private: ...}).
"private" ist der Default, dass müsste man nicht unbedingt eintippen.
Und wie würde man den Sachverhalt "private/interne Variable in einem
struct" in C darstellen? Das muss auch irgendwie dokumentiert werden.
>> Meine Erfahrung ist die, dass C++-Quelltexte kleiner sind :-)>> Das sind sie auch, sobald man Dinge wie die STL nutzen kann/darf, aber> eben nur dann.
Wenn man ein ein C++-Feature nicht nutzen darf, dann wird das
"C-Äquivalent im C++-Quelltext" auch nicht länger.
Selbst wenn man reines C mit einem C++-Compiler verwendet, ergeben sich
Vorteile: Zusätzliche Warnings, typsichere enums.
Yalu X. schrieb:> Oft würden die Entwickler gerne C++ verwenden, aber der Chef oder die> Firmenphilosophie schreiben C vor.
Ja, das erlebe ich leider immer wieder: Wenn es irgendwelche Regularien
gibt oder es organisatorisch nicht passt oder nicht gewollt ist. Das ist
allerdings eine andere Diskussion; technisch würde ich sagen, dass
nichts gegen C++ spricht.
Roland H. schrieb:> Dem steht die Verwendung von "this" gegenüber, und das spart eine ganze> Menge Tipperei.
Ich habe nicht den Eindruck, dass beim Programmieren wirklich die
Tipparbeit im Vordergrund steht. Allerdings weiss ich natürlich nicht,
wie langsam ihr tippt. ;-)
Yalu X. schrieb:> Wenn man alle Funktionen als Methoden in Klassen packt, muss man jeden> Methodenkopf doppelt schreiben, einmal in der Klassendeklaration und> einmal in der Methodendefinition.
Also ob das im copy-and-paste Zeitalter viel Arbeit darstellte.
Simon Budig schrieb:> C++ ist ein schlecht gestaltetes Amalgam aus verschiedenen> Programmiersprachenkonzepten, das mit Gewalt in eine C-artige> Erscheinungsform gepresst wurden.
Damit hast du nicht ganz unrecht, aber diese "Amalgame" (zu denen auch
Java, Objective-C und C# gehören), sind die Mainstream-Programmier-
sprachen. Im Tiobe-Index belegen sie zusammen einen Anteil von über 40%,
zusammen mit ihrem gemeinsamen Vorfahr C sind es sogar über 60%. Wegen
der steigenden Popularität von Objective-C (iPhone-Effekt) zeigt die
Tendenz sogar nach oben.
A. K. schrieb:> Ich habe nicht den Eindruck, dass beim Programmieren wirklich die> Tipparbeit im Vordergrund steht.
Objektiv gesehen nicht, aber mitunter subjektiv :)
> Allerdings weiss ich natürlich nicht, wie langsam ihr tippt. ;-)
Seeehr langsam ;-)
> Also ob das im copy-and-paste Zeitalter viel Arbeit darstellte.
So sehr viel vielleicht nicht, aber:
- Ein gewisser Zusatzaufwand ist trotzdem vorhanden, zumal die Sache mit
dem Copy/Paste einer Zeile ja noch nicht ganz getan ist.
- Es ist eine dieser "niederen" Tätigkeiten, die insbesondere dann für
Unmut sorgt, wenn die Zeit gerade knapp ist.
- Denken macht einfach mehr Spaß als Tippen.
- Die Alternativen stehen ja bereit und warten nur darauf, genutzt zu
werden. Und das mache ich dann eben, wenn keine anderen triftigen
Gründe dagegen sprechen.
Yalu X. schrieb:> Damit hast du nicht ganz unrecht, aber diese "Amalgame" (zu denen auch> Java, Objective-C und C# gehören), sind die Mainstream-Programmier-> sprachen.
Ja, populär ist C++ ohne jeden Zweifel. C++ gehört sicher zu den
Sprachen mit denen man halbwegs klarkommen sollte, wenn man in der Wahl
seiner Werkzeige nicht 95%ig frei ist... :)
Ich würde aber C++ nicht in einen Topf mit Java und C# werfen wollen.
Meine Erfahrung mit Java sind sehr begrenzt, mit C# nicht vorhanden.
Aber trotzdem haben sie nur eine oberflächliche syntaktische Ähnlichkeit
mit C++. Was meines Wissens sowohl Java als auch C# qualitativ deutlich
von C++ abhebt ist, dass sie ein sauberes Objektmodell haben (was bis
auf die Ebene der VM hinuntergeht). Sie haben sich soweit von den
Strukturen von C gelöst, dass sie eben nicht mehr noch mit Krampf
"kompatibel" zu C sind. Da hat sich jemand hingesetzt und sorgfältig
drüber nachgedacht, was man (noch) braucht, was man über Bord wirft und
was man neu erfinden muss.
C# gehört - trotz meiner Animositäten gegenüber Microsoft - definitiv zu
den Sachen die ich mir ansehen will, auch weil ich von Leuten deren
Kompetenz ich sehr achte gehört habe, dass es gegenüber Java die
sauberere Sprache sein soll.
Bei C++ hat Stroustroup C hergenommen und geguckt wie man da Objekte
reinbauen kann. Objekte sind wie structs, aber das darf man ja nicht
laut sagen, also nehmen wir "class" - sonst sieht das ja nicht neu aus.
Oh, und wir müssen Operatoren überladen können, also nehmen wir mal
"operator++()" her. Oh, da gibt es ja noch die Postfix-Variante, da
nehmen wir dann "operator++(int)" mit einem ungenutzten Dummy-Argument
(WTF?). Und in einer anderen Sprache habe ich mal auf Textersetzung
basierende Programmierung gesehen, da erfinde ich jetzt mal Templates
mit einer komplett von C abgekoppelten Infrastruktur. Oh, und der
Shift-Operator sieht grafisch so ähnlich aus wie Richtungspfeile, das
können wir gut für IO-Operationen verwenden...
Oh, und damit wir niemand verschrecken behalten wir C als Subset. Und
wenn es in Details dann eben doch nicht kompatibel ist dann ignorieren
wir das Problem.
Verdammt, es wird ein Rant... :)
C++ wurde entwickelt indem man C hergenommen hat und dann rangeflanscht
hat ohne mal einen Schritt zurückzutreten und sich das Resultat als
ganzes mal anzugucken. Bei Java und C# war mehr Sorgfalt am Werk.
> Im Tiobe-Index belegen sie zusammen einen Anteil von über 40%,> zusammen mit ihrem gemeinsamen Vorfahr C sind es sogar über 60%. Wegen> der steigenden Popularität von Objective-C (iPhone-Effekt) zeigt die> Tendenz sogar nach oben.
Ja, unbestritten. Auch PHP hat Syntaxelemente die ähnlich wie C
aussehen. Auch PHP wird von vielen tausenden Leuten eingesetzt. Und in
der Tat ist PHP noch dramatisch viel schlechter als C++...
Für mich ist die Ästhetik von Programmiersprachen wichtig. Sicherlich
spielt dabei eine Rolle, dass ich als Mathematiker klare Strukturen
suche und ein "Hauptsache es funktioniert" nicht reicht damit ich mich
wohlfühle. Aber meistens komme ich damit klar, wenn ich gelegentlich
einen Rant loslassen kann... :)
Viele Grüße,
Simon
Ich bin nicht sicher, ob Graphical User (Gast) auch die ganz kleinen
Mikrocontroller im Sinn hat. Jedenfalls gibt es einige, die keinen Stack
haben. Sie können in C eingeschränkt programmiert werden, C++ geht
darauf aber gar nicht.
Ich habe schonmal einen Mikrocontroller mit 2KB Ram in C++ programmiert,
dabei allerdings viel mit statischen Objekt-Instanzen gearbeitet. Alle
anderen Mikrocontroller-Projekte habe ich allerdings in Assembler oder C
programmiert.
Ich hatte nicht das Gefühl, dass C++ mir in diesem Projekt signifikante
Vorteile gebracht hat. Es war daher bei einem einmaligen Versuch
geblieben.