Forum: Mikrocontroller und Digitale Elektronik Mikrocontroller in C++ oder C Programieren


von Simon (Gast)


Lesenswert?

Hey Leute,

ich habe eine Frage an euch bzw würde gerne eure Erfahrungen hören!

Heute behauptete ein Bekannter von mir das man Mikrocontroller besser 
mit C++ programmieren kann als in C.
Auf meine Frage warum das so sei, sagte er das man in C++ quasi mehr und 
präzisere Werkzeuge habe als mit reinem C.

Da ich bisher nur in C programmiert habe und mich mit C++ nicht gut 
auskenne, würde ich gerne ein Paar Meinungen dazu hören.

Danke :)

von rmu (Gast)


Lesenswert?

Es kommt hauptsächlich darauf an wer programmiert. Die 
Programmiersprache ist an und für sich wurscht.

von Simon (Gast)


Lesenswert?

Hat eine gewisse Sprache denn Vorteile gegenüber der anderen?

von Sebastian V. (sebi_s)


Lesenswert?

Da C++ bis auf wenige Ausnahmen auch alle Features von C enhält und dazu 
noch einen Haufen neuer Features, ist C++ deutlich mächtiger (und 
komplizierter). Wenn man weiß wie man mit den neuen Features umgeht und 
welche davon auch für Mikrocontroller geeignet sind dann sehe ich in der 
Verwendung von C++ auf Mikrocontrollern eigentlich nur Vorteile. Wobei 
jetzt auch wieder einige Leute behaupten werden, dass nur das "erste" C 
nach K&R (oder Assembler) das einzig Wahre ist.

von rmu (Gast)


Lesenswert?

Ja sicher, jede der beiden Sprachen hat Vorteile gegenüber der anderen, 
nur halt andere.

C ist auf alle Fälle einfacher. C++ hat mächtige Werkzeuge zur 
Abstraktion (templates).

von Alexander S. (alesi)


Lesenswert?


von Stefan F. (Gast)


Lesenswert?

Du kannst in C fast alle Features des Mikrocontrollers voll ausnutzen. 
In C++ ebenfalls.

In Assembler kannst du alle Features ausnutzen. Ich würde trotzdem C 
oder C++ bevorzugen, soweit möglich.

Ein korrektes C Programm ist nicht schlechter als das selbe Programm in 
C++ Programm.

Man kann daher nicht pauschal sagen, welche Sprache besser ist.

Deine Frage ist in etwas wie: Was ist besser, ein gewöhnlicher Hammer 
oder ein Dachdecker-Hammer? Zum Nägel in die Wand treiben eignen sich 
beide gleich gut.

von c-hater (Gast)


Lesenswert?

Sebastian V. schrieb:

> Da C++ bis auf wenige Ausnahmen auch alle Features von C enhält und dazu
> noch einen Haufen neuer Features, ist C++ deutlich mächtiger (und
> komplizierter). Wenn man weiß wie man mit den neuen Features umgeht und
> welche davon auch für Mikrocontroller geeignet sind dann sehe ich in der
> Verwendung von C++ auf Mikrocontrollern eigentlich nur Vorteile. Wobei
> jetzt auch wieder einige Leute behaupten werden, dass nur das "erste" C
> nach K&R (oder Assembler) das einzig Wahre ist.

Das ist eigentlich ganz simpel: je höher der Abstraktionsgrad der 
Sprache, desto mehr kann sie für einen tun (wenn man sie beherrscht 
natürlich nur). Der Nachteil ist aber auch (zumindest tendentiell) 
immer, dass sie dazu zur Laufzeit für das gleiche Problem mehr Resourcen 
erfordern wird als eine weniger abstrakte Sprache.

C++ vs. C, ist ein sehr schönes Beispiel für dieses Prinzip (was sich im 
übrigen ganz zwanglos aus den Grundgesetzen der Informatik herleiten 
läßt). C++ kann (bezüglich des Ressourcenbedarfs) immer genau dann 
gerade so mit C mithalten, wenn man auf die tatsächlich vorteilhaften 
Features von C++ komplett verzichtet...

Tendenziell ähnlich, aber doch im Detail durchaus anders ist es bei C 
vs. Asm. Da kann C gerade so mit Asm mithalten, wenn man zumindest an 
den kritischen Stellen auf die vorteilhaften Features von C verzichtet. 
Was allerdings in diesem Fall zumindest gelegentlich bedeutet, gleich 
ganz auf C verzichten zu müssen, weil der Impact des verbleibenden Rests 
einfach viele sinnvolle Optimierungen an den wirklich kritischen Stellen 
nicht zuläßt oder zumindest erheblich schwerer macht.

von Sebastian V. (sebi_s)


Lesenswert?

c-hater schrieb:
> wenn man auf die tatsächlich vorteilhaften
> Features von C++ komplett verzichtet...

Was ist mit den Features die zur Compilezeit ausgeführt werden?

von A. S. (Gast)


Lesenswert?

Probiere C++ aus, aber hüte Dich davor, globale, reale Hardware (IO) 
unbedingt in OOP zwängen zu wollen. Vermeide RTTI und hüte Dich vor 
sorglosem Umgang mit Exceptions. Die sind oftmals nur dann sinnvoll, 
wenn ein kognitiver Benutzer eingreifen kann.


c-hater schrieb:
> Tendenziell ähnlich, aber doch im Detail durchaus anders ist es bei C
> vs. Asm. Da kann C gerade so mit Asm mithalten, wenn man zumindest an
> den kritischen Stellen auf die vorteilhaften Features von C verzichtet.
> Was allerdings in diesem Fall zumindest gelegentlich bedeutet, gleich
> ganz auf C verzichten zu müssen, weil der Impact des verbleibenden Rests
> einfach viele sinnvolle Optimierungen an den wirklich kritischen Stellen
> nicht zuläßt oder zumindest erheblich schwerer macht.

Das stimmt einfach nicht. Der Unterschied zwischen C und Assembler ist 
wie der zwischen Schreibmaschine und Textverarbeitung. Wenn ich ein 
Programm oder eine Funktion genau einmal brauche und runterhacke, dann 
kann Assembler effektiver sein. Der C-Compiler schlägt den Assembler 
aber, wenn
 - strukturiert, lesbar, wiederverwendbar programmiert wird
 - ich nicht alle Tricks und Kniffe zur Optimierung kenne
 - ich die Opcodes und deren Dauer nicht genau im Kopf habe
 - wenn der Code sich fleißig ändert (und ich nicht jede Zeile neu 
optimiere)
Zudem ist C um Größenordnungen produktiver bei Plattformwechseln oder 
Verwendung von externem Code.

Brächte C++ auch nur einen Bruchteil dieser Effektivitätssteigerung 
gegenüber C im Low-Level-Bereich (OS, µC, Safety, konkrete IO), dann 
wäre der Linux-Kernel seit 10 Jahren auf C++ portiert und C wäre ein 
Exot. Auf der anderen Seite wäre Assembler schon 20 Jahre bedeutungslos, 
wenn heutige C-Compiler für Pics, Avrs und Co schon damals verfügbar 
gewesen wären. Bei C++ ist das kein limitierender Faktor.

Es macht einfach wenig Sinn, die unbestreitbaren Vorteile der OOP oder 
Funktionalen Programmierung bei virtuellen Objekten (GUIs, Datensätze, 
Webseiten, allgemeine Interfaces) auf dedizierte zu kontrollierende 
Objekte zu übertragen. Genau wie es einige Jahre dauerte, die guten 
gotos aus der Masse der schlechten herauszuschälen, dauert es noch ein 
paar Jahre, die guten globalen Variablen prozeduraler Verarbeitung aus 
der Masse des Spaghetticodes herauszufiltern.

von Nop (Gast)


Lesenswert?

Simon schrieb:
> Auf meine Frage warum das so sei, sagte er das man in C++ quasi mehr und
> präzisere Werkzeuge habe als mit reinem C.

Man hat mehr Werkzeuge, ja. Aber man muß in C++ dafür ein besserer 
Programmierer sein als für reines C.

Der Grund ist, daß man für C++ nicht nur wissen muß, wie man welche 
Features nutzt, sondern man muß auch sehr gut verstanden haben, was 
"unter der Haube" bei C++ abgeht und welche Features man daher nicht 
benutzen darf. Und dann muß man auch mit dem eingeschränkten Set an 
Features in C++ immer noch gut sein.

Wenn man das alles kann und die deutlich zahlreicheren C++-Fallstricke 
meidet (die auf dem PC keine Rolle spielen), dann ist C++ weder 
langsamer noch ressourcenintensiver.

Dummerweise sind C++-Programmierer, die das können, dann auch 
entsprechend teurer als C-Programmierer, die ein funktional 
gleichwertiges Programm erstellen können. Eben weil solche 
C++-Programmierer auch deutlich komplexere Jobs anderswo mit besserer 
Bezahlung haben können. Kommerziell spricht das gegen C++.

Ich persönlich finde C++ eher hinderlich, weil man zwar die höhere 
Abstraktion hat, aber man muß dauernd durch sie hindurchsehen und zu Fuß 
zuende denken, anstatt sie einfach so zu nutzen. Wodurch für mein 
Empfinden der Compiler mir eher im Weg steht.

Das ist aber nur meine persönliche Meinung, das werden andere anders 
sehen. In C++-Kreisen ist diese Einstellung nämlich als "C hacker 
syndrome" verpönt. Andererseits kannst Du bei zertifizierten Projekten 
nunmal nicht haufenweise Libraries einbinden wie auf dem PC, so daß man 
bei sowas mit dem "C hacker syndrome" schon gut aufgehoben ist.

Bei C gibt es relativ wenig, was man meiden sollte. Sämtliche dynamische 
Speicherverwaltung mit malloc sollte man unterlassen, und man sollte 
sich über den enormen Ressourcenbedarf von printf und Konsorten bewußt 
sein.

De facto ist C++ auf Microcontrollern eher ein C+. C mit Klassen, mehr 
oder weniger. Es sei denn, man geht auf die großen Cortex-A, wo ein 
volles Linux drunterläuft, das ist dann aber auch schon eher 
Applikationsprogrammierung.

von Stefan (Gast)


Lesenswert?

Du kannst sogar auf einem 8-Bit Mikrocontroller C++ mit ein paar 100 
Bytes Ram benutzen, wenn Du weißt, was Du tust und auf einige 
Schlüsselfeatures von C++ verzichtest. Dynamische Allokation am Heap 
oder Polymorphie solltest Du gleich vergessen. C++ auf MC ist ganz 
anders zu benutzen als in der PC-Programmierung oder so. Und Techniken, 
die Du von Java vielleicht kennst, sowieso.
Dagegen statische Template-Klassen mit Wertparametern sind sehr OK. 
Allerdings musst Du wissen, was passiert. D.h. du musst es so machen, 
dass keine Codereplikation passiert und z.B. explizite 
Template-Instanziierung benutzen.
Wenn Du nicht genau weißt, was C++ ist, und was der Compiler aus Deinem 
Code macht, dann programmiere lieber in C. Objektorientierung kannst Du 
auch in C - dann halt explizit ausprogrammiert. Das mach ich z.B. dann 
auch, wenn MISRA-C gefordert ist.
S.

von c-hater (Gast)


Lesenswert?

Sebastian V. schrieb:

> Was ist mit den Features die zur Compilezeit ausgeführt werden?

Das sind letztlich nichts anderes als Macros, wie man sie auch in C oder 
sogar Asm haben kann. Ist nur eine Frage des Geschicks bei der 
Macro-Programmierung.

Klar: wenn man C++ benutzt, spart man diese Macroprogrammierung.

Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN.

Man muss dann nämlich ganz genau wissen, wie der C++-Compiler seine 
Syntaxblähungen umsetzt. Dieser Zustand ist keinesfalls leichter zu 
erreichen, als wenn man die Macros gleich selbst verfasst...

Bei selbst verfassten Macros hat man nämlich einen relativ leicht 
nachvollziehbaren Quelltext vorliegen. Bei dem Kram, den der Compiler 
tut, ist man auf eine meist unzureichende, ziemlich veraltete (aber 
trotzdem überaus längliche) Dokumentation allein der Wirkungen fremden 
Codes angewiesen...

Wer sich das freiwillig antut, nur um einen AVR8 in C++ zu 
programmieren, ohne gegenüber C nennenswerte Performancenachteile zu 
erleiden, der ist in meinen Augen nicht ganz sauber in der Rübe. 
Assembler lernen wäre sehr viel sinnvoller. Denn wenn man das wirklich 
kann, kann man gegenüber C massive Performancevorteile erringen. Der 
Aufwand hat sich dann wenigstens gelohnt, weil er einen messbaren 
Vorteil bringt, wohingegen dieser C++-Desingtime-Kram doch eher eine 
rein akademische Machbarkeitstudie darstellt. Brotlose Kunst...

Sieht man ja im parallel laufenden Thread (läuft der noch?). Der Code 
ist in der Lage, ohne nennenswerte Verluste gegenüber C auf EINER ganz 
konkreten Maschine zu laufen. Na wenn das kein Erfolg ist...

In C oder Assembler ist es ziemlich leicht, den Code für große Teile der 
gesamten Zielarchitektur lauffähig zu machen. Ich bin gespannt, wie weit 
dieser C++-ler kommt und vor allem darauf, wieviel dann von dem Ansatz 
überbleibt, mit den Sprachmitteln von C++ Code zu erzeugen, der zur 
Laufzeit zumindest so effizient wie C ist...

Vermutlich wird es auf eine Lösung á la Arduino hinauslaufen: 100+ 
Takte, um einen Pin zu togglen...

von Wilhelm M. (wimalopaan)


Lesenswert?

Jeder Thread mit diesem Thema artet früher oder später aus :-( Leider! 
Es werden persönliche Angriffe losgelassen, das kann ich nicht 
verstehen.

Jeder soll das so machen wie er möchte!

Ich erkenne an, dass bei Assembler manches vllt schneller (Laufzeit) 
geht. Aber sicher nicht plattform-neutral. Und ich erkenne auch an, dass 
man C-Code man eben schnell hingeschrieben hat, um eine Led blinken zu 
lassen.

Mit C++ kann man ein Niveau erreichen, was fast an plattform-Neutralität 
grenzt. Beides muss man gegeneinander abwägen, aber nicht niedermachen.

Ich gebe allerdings zu bedenken, dass man mit (statischer) 
parametrischer Polymorphie (aka templates in C++) und vielen anderen 
tollen neuen(!!!) features von C++ (v.a. variadische templates und 
constexpr functions) unwahrscheinlich nah an der Code-Größe und 
Performance von Assembler dran ist.

Als nächstes sehe ich dann den Punkt Wartbarkeit als ganz wichtiges. 
Jeder mit einem Kenntnisstand von C++98 sollte der Fairness halber 
einfach mal C++14/C++17/C++20 Code ansehen und probieren (auf dem Host 
oder uC: der avr-gcc >= 6.2 machts möglich bzw. clang++/g++ auf dem 
Host).

Und ja, wer sonst auch in C++ programmiert und dort auch große 
Software-Artefakte außerhalb der uC Welt erstellt, dem fällt es 
natürlich leichter auch auf dem uC damit klar zu kommen. Ein Java oder 
Python Mensch hat es da schon wesentlich schwerer. Will sagen: ein 
vorgebildeter C++-Programmier hat vllt schneller etwas in C++ 
hingeschrieben als jemand anderes in asm oder C.

VG
 Wilhelm

von Sheeva P. (sheevaplug)


Lesenswert?

c-hater schrieb:
> Sebastian V. schrieb:
>
>> Was ist mit den Features die zur Compilezeit ausgeführt werden?
>
> Das sind letztlich nichts anderes als Macros, wie man sie auch in C oder
> sogar Asm haben kann. Ist nur eine Frage des Geschicks bei der
> Macro-Programmierung.
>
> Klar: wenn man C++ benutzt, spart man diese Macroprogrammierung.
>
> Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN.

Typsicherheit.

> Vermutlich wird es auf eine Lösung á la Arduino hinauslaufen: 100+
> Takte, um einen Pin zu togglen...

Das ist so ziemlich das schlechteste Beispiel, das es gibt, und 
natürlich hast Du es mit großem Bedacht gewählt. Arduino ist entwickelt 
worden, um es Leuten ohne technischen Hintergrund zu ermöglichen, 
möglichst einfach und ohne größeren Lernaufwand fertige 
Mikrocontrollerplatinen zu programmieren. Dabei geht es ausdrücklich 
nicht um Effizienz, minimale Codegröße oder gar um Softwareentwicklung 
für die Massenproduktion, sondern um größtmögliche Vereinfachung und 
maximale Fehlertoleranz. Und dabei war und ist Arduino ausgesprochen 
erfolgreich, ob Du es verstehen willst oder meinetwegen auch nicht.

von Sebastian V. (sebi_s)


Lesenswert?

c-hater schrieb:
> Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN.

Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde 
ich C++ jederzeit vorziehen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Und ich würde ungern auf Templates verzichten: ich lasse lieber Code 
erzeugen als es selbst zu tun ;-)

: Bearbeitet durch User
von Artur S. (Gast)


Lesenswert?

Sebastian V. schrieb:
> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde
> ich C++ jederzeit vorziehen.

Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren 
Seite.

von Wilhelm M. (wimalopaan)


Lesenswert?

Was das mit der Architektur des uC zu tun???

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Artur S. schrieb:
> Sebastian V. schrieb:
>> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde
>> ich C++ jederzeit vorziehen.
>
> Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren
> Seite.

Das ist auch wieder ein schönes Beispiel dafür, dass beim Stichwort C++ 
jeder was dazu schreiben muss, der irgend wie mal davon gehört hat.

Überladene Funktionen werden immer zur Compilerzeit anhand der 
Argumente ausgewählt (und um zu dieser Erkenntnis zu kommen, muss man 
jetzt auch nicht 10 Jahre C++ gemacht haben)!

in C:
1
    IntSinD(1.3);
2
    IntSinF(1.4f);

in C++
1
    using intrinsics::sin;
2
    sin(1.3);
3
    sin(1.4f);

Der generierte Code wird exakt der selbe sein.

Es gibt Unmengen von features in C++, die überhaupt keine Laufzeitkosten 
haben. Z.B:
- Funktionsüberladungen
- namespaces
- operators
- nicht polymorphe Klassen
- scoped enumerations
- const correctness
- präzisere casts
- stärkere Typsicherheit
- uvm.

mfg Torsten

von nicht"Gast" (Gast)


Lesenswert?

Artur S. schrieb:
> Sebastian V. schrieb:
>> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde
>> ich C++ jederzeit vorziehen.
>
> Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren
> Seite.

na wie immmer, gesundes Halbwissen :)

von Artur S. (Gast)


Lesenswert?

Artur S. schrieb:
> Sebastian V. schrieb:
>> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde
>> ich C++ jederzeit vorziehen.
>
> Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren
> Seite.

Mit meiner Bemerkung ging es mir um "würde ich C++ jederzeit vorziehen".
Das kann man sich so absolut behauptet erst mit einem gut ausgestatteten 
Controller erlauben. Ob der dann sinnvoll für jede Anwendung ist steht 
auf einem anderen Blatt.

von Findelkind (Gast)


Lesenswert?

Torsten R. schrieb:
> Es gibt Unmengen von features in C++, die

alle zu erlernen und richtig anzuwenden sind!
Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik 
aus dem Elfenbeinturm.

von Wilhelm M. (wimalopaan)


Lesenswert?

Findelkind schrieb:
> Torsten R. schrieb:
>> Es gibt Unmengen von features in C++, die
>
> alle zu erlernen und richtig anzuwenden sind!
> Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik
> aus dem Elfenbeinturm.

Mmh, sowohl C als auch RISC als Architekturmerkmal stammen aus 
Elfenbeintürmen ...

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Findelkind schrieb:

> Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik
> aus dem Elfenbeinturm.

Das hat relativ wenig mit Hirnakrobatik zu tun. Vielmehr mit der Größe 
des Werkzeugkastens. Ich kann zur Lösung meiner Aufgaben auf viel mehr 
Sprachmittel zurück greifen. Und viele diese Sprachmittel dienen 
letztendlich dazu, Fehler möglichst bereits zur Compile-Zeit zu finden. 
Währen Du also noch dein K&R C Program debuggst, habe ich mein C++ 
Program schon fertig und liege schon auf der Couch und guck mir mal die 
neuen Sprachmittel von C++17 an ;-)

Ich bin ja schon immer erstaunt, wie wenig embedded C Entwickler C99 
nutzen (immerhin auch schon 17 Jahre alt).

mfg Torsten

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Wilhelm M. schrieb:
> Ich gebe allerdings zu bedenken, dass man mit (statischer)
> parametrischer Polymorphie (aka templates in C++) und vielen anderen
> tollen neuen(!!!) features von C++ (v.a. variadische templates und
> constexpr functions) unwahrscheinlich nah an der Code-Größe und
> Performance von Assembler dran ist.

 Lol, was ein hohles Argument. Natürlich erzeugt der C++ wahrscheinlich
 effizienteren Code als der Programierer - nur gilt das eben nur für
 diese unnützen Funktionen und Features, die kein normaler Mensch jemals
 bei einem 8-bit AVR oder PIC brauchen wird- selbst bei enem ARM nicht.

 Und OOP bei uC - einfach lachhaft. Das kann vielleicht bei einer
 Ampelsteuerung oder Strassenbeleuchtung einigermassen zufriedenstellend
 funktionieren, aber bestimmt nicht bei schnellen Industriesteuerungen
 oder ähnlich anspruchsvollen Anwendungen.
 Liest doch mal ein bisschen über C++ - da sind so viele Situationen
 undefiniert, da kriegt man einen Lachkrampf schon bei oberflächlichem
 durchlesen.

 Für Windows und Buchhaltungs und Database Kram zu gebrauchen, für uC
 absolut keine Vorteile, ausser das man rumposaunen kann, dass es in
 C++ programmiert ist.
 Das es im Endeffekt nur auf Legosteine zusammensetzen rausläuft, wird
 gerne übersehen...

Torsten R. schrieb:
> Währen Du also noch dein K&R C Program debuggst, habe ich mein C++
> Program schon fertig und liege schon auf der Couch und guck mir mal die
> neuen Sprachmittel von C++17 an ;-)

 Oder in irgendeinem Forum Arduino benutzer anspucken, auch wenn diese
 genau dasselbe machen wie du...

: Bearbeitet durch User
von rmu (Gast)


Lesenswert?

c-hater schrieb:
> Klar: wenn man C++ benutzt, spart man diese Macroprogrammierung.
>
> Aber hat man dadurch wirklich etwas gewonnen? Ganz klares NEIN.

Doch, hat man, das Zeug ist typsicher. C-Makros sind ganz doofe 
Textersetzung, wenn da der Wurm drin ist kanns ganz schön umstänglich 
sein, das zu debuggen.

> Man muss dann nämlich ganz genau wissen, wie der C++-Compiler seine
> Syntaxblähungen umsetzt. Dieser Zustand ist keinesfalls leichter zu
> erreichen, als wenn man die Macros gleich selbst verfasst...
>
> Bei selbst verfassten Macros hat man nämlich einen relativ leicht
> nachvollziehbaren Quelltext vorliegen. Bei dem Kram, den der Compiler
> tut, ist man auf eine meist unzureichende, ziemlich veraltete (aber
> trotzdem überaus längliche) Dokumentation allein der Wirkungen fremden
> Codes angewiesen...

Bei selbst verfassten templates auch.

Makros sind nicht automatisch leicht nachvollziehbar. Da gibts Beispiele 
in denen ein Makro per inline-assembler eine Shell füttert und den 
Output selbiger ins Programm reinnudelt. Total unverständlich.

> Wer sich das freiwillig antut, nur um einen AVR8 in C++ zu
> programmieren, ohne gegenüber C nennenswerte Performancenachteile zu
> erleiden, der ist in meinen Augen nicht ganz sauber in der Rübe.

Dass sich das niemand antut wenn er nennenswerte Performancenachteile 
erleiden würde ist ja klar, oder?

> Assembler lernen wäre sehr viel sinnvoller. Denn wenn man das wirklich
> kann, kann man gegenüber C massive Performancevorteile erringen. Der
> Aufwand hat sich dann wenigstens gelohnt, weil er einen messbaren
> Vorteil bringt, wohingegen dieser C++-Desingtime-Kram doch eher eine
> rein akademische Machbarkeitstudie darstellt. Brotlose Kunst...

Da lernt man dann eine Architektur, und bei der nächsten ist alles ganz 
anders. Davon abgesehen sind z.B. die ARMs recht mühsam in ASM zu 
programmieren, abgesehen davon ist es Wahnsinn, einige zig Kilobyte an 
Maschinencode in Assembler zu erstellen.

> In C oder Assembler ist es ziemlich leicht, den Code für große Teile der
> gesamten Zielarchitektur lauffähig zu machen. Ich bin gespannt, wie weit
> dieser C++-ler kommt und vor allem darauf, wieviel dann von dem Ansatz
> überbleibt, mit den Sprachmitteln von C++ Code zu erzeugen, der zur
> Laufzeit zumindest so effizient wie C ist...

In C++ lässt sich ohne weiteres Code erstellen, der effizienter als 
äquivalenter C-Code läuft, dabei kürzer und weniger fehleranfällig ist.

Die Leute, die C++ kategorisch ablehnen, tun das meistens nur deswegen, 
weil sie einfach aus Prinzip nichts Neues (mehr) anfangen wollen. Sollen 
sie halt weiter in ihrem 1er Golf herumfahren, während der Stand der 
Technik längst Airbags, Vollverzinkung, Kat, dabei 3mal so viel 
Motorleistung bei weniger Verbrauch ist.

Funktionsüberladungen, templates, namespaces, überladene operatoren, 
inline-Funktionen, lambdas, static_assert, "RAII" etc. machen Code 
übersichtlicher, korrekter, wartbarer, und haben keine negativen 
Auswirkungen auf Laufzeit oder Codesize im Vergleich zu C, vorausgesetzt 
die/der Author/in weiss was man tut. Eine nicht-vollständige Liste wo 
C++ auch auf Mikrokontrollern massiv Sinn macht: mit "Policies" kann man 
die Quellen auf eine Art und Weise entkoppeln und gleichzeitig doch zur 
Compilezeit binden, wie das in C nur durch eine Art Meta-Compiler 
möglich wäre und/oder zur Laufzeit umständlichen und kostspieligen 
Funktionspointer-Overhead hätte.

von Christopher C. (trihexagon)


Lesenswert?

c-hater schrieb:
> Man muss dann nämlich ganz genau wissen, wie der C++-Compiler seine
> Syntaxblähungen umsetzt. Dieser Zustand ist keinesfalls leichter zu
> erreichen, als wenn man die Macros gleich selbst verfasst...
>
> Bei selbst verfassten Macros hat man nämlich einen relativ leicht
> nachvollziehbaren Quelltext vorliegen. Bei dem Kram, den der Compiler
> tut, ist man auf eine meist unzureichende, ziemlich veraltete (aber
> trotzdem überaus längliche) Dokumentation allein der Wirkungen fremden
> Codes angewiesen...

Warum verzichtest du nicht lieber auf C-Blähcode und musst dich nicht 
auf fremde Software verlassen (namens Compiler), wenn du das Gleiche mit 
einem Macroassembler machen kannst? Erkennst du die Analogie?

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Marc Vesely schrieb:

>  Oder in irgendeinem Forum Arduino benutzer anspucken, auch wenn diese
>  genau dasselbe machen wie du...

Ich käme im Leben nicht auf die Idee.

von rmu (Gast)


Lesenswert?

Marc V. schrieb:
> Liest doch mal ein bisschen über C++ - da sind so viele Situationen
>  undefiniert, da kriegt man einen Lachkrampf schon bei oberflächlichem
>  durchlesen.

Was soll da konkret "undefiniert" sein, was in C nicht "undefiniert" 
ist?

Der Lachkrampf gibt sich eventuell von selbst wenn man sich weniger 
oberflächlich mit dem Thema beschäftigt, eventuell geht einem dann auch 
ein Licht auf.

von Mikro 7. (mikro77)


Lesenswert?

Simon schrieb:

> Heute behauptete ein Bekannter von mir das man Mikrocontroller besser
> mit C++ programmieren kann als in C.
> Auf meine Frage warum das so sei, sagte er das man in C++ quasi mehr und
> präzisere Werkzeuge habe als mit reinem C.

Ich denke, mit keiner anderen Sprache kann man Typsicherheit zur 
Compilezeit so gut sicher stellen wie mit C++. Dadurch sind prinzipiell 
schnellere, zuverlässige und kleinere Programme möglich als mit C (egal 
auf welcher Plattform).

> Da ich bisher nur in C programmiert habe und mich mit C++ nicht gut
> auskenne, würde ich gerne ein Paar Meinungen dazu hören.

Das "Problem" bei C++ sind die Freiheitsgrade. Der Programmierer kann 
machen was er will. Zudem ist die Sprache komplex (zusammen mit der 
STL), die sich mit mit C++11 quasi verdoppelt hat. Wenn man sich nicht 
bewußt ist, was man da macht, werden C++ Programme schnell zu langsamen 
und unwartbaren Monstren.

Wenn du aus der C-Welt kommst und mit dem Gedanken spielst, einen C++ 
Compiler zu verwenden, dann überlege dir was dich in C meisten stört, 
und gucke ob es etwas besseres in C++ gibt. -- Auf Anhieb würden mir 
Namespaces einfallen. Smart Pointer sind die Antwort auf Memory Leaks. 
Statische Klassen sind "hübscher", als einen Set von Funktionsaufrufen 
um eine struct zu basteln... also weiterhin "C" mit ein paar kleinen 
Verbesserungen. Und dann Stück für Stück. :-)

von rmu (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Mmh, sowohl C als auch RISC als Architekturmerkmal stammen aus
> Elfenbeintürmen ...

Wo kommen denn diese Ansichten her?

C ist definitiv nicht in einem Elfenbeinturm entstanden, ganz im 
Gegenteil ist das von einem formalen Standpunkt aus recht grausame 
Sprache, die viele Grausamkeiten wie undefiniertes Verhalten zulässt. 
Eine Elfenbeinturm-Sprache ist z.b. Haskell, aber selbst die taugt für 
"richtigen" Einsatz.

RISC ist auch aus sehr konkreten und praktischen Motivationen 
entstanden, und es ist kein Zufall, dass alle effizienten stromsparenden 
Prozessorarchitekturen die es heute noch gibt irgendwo einen 
RISC-artigen Maschinenkode haben.

von A. S. (Gast)


Lesenswert?

rmu schrieb:
> In C++ lässt sich ohne weiteres Code erstellen, der effizienter als
> äquivalenter C-Code läuft, dabei kürzer und weniger fehleranfällig ist.

Beispiele für effizienter?

[BTW: Ich denke, um nicht Äpfel und Birnen zu vergleichen, muss bei C im 
Hinterkopf Misra und PC-Lint mitschwingen. Nicht, dass man Misra 
einhält, sondern dass man die Forderungen nachvollziehen kann und das 
PC-Lint noch mehr prüft.

Zudem halte ich persönlich z.B. Namespaces und Polymorphie für einen 
Scheinvorteil. Darum akzeptiere ich zwar, wenn jemand kürzer und 
robuster schreibt, teile das aber bei großen Projekten (>> 1E5 Loc nicht 
unbedingt)]

von Vincent Samos (Gast)


Lesenswert?

Die Anwendung immer komplexerer abstrakter Sprachen ist eine Medaille 
mit zwei Seiten: Was sich mit sinnvoller Verknüpfung zahlloser Features 
hinterher an Zeit sparen ließe mußte vorab erstmal zur Beherrschung der 
Sprache investiert werden:

Mikro 7. schrieb:
> Zudem ist die Sprache komplex (zusammen mit der
> STL), die sich mit mit C++11 quasi verdoppelt hat. Wenn man sich nicht
> bewußt ist, was man da macht, werden C++ Programme schnell zu langsamen
> und unwartbaren Monstren.

Entsprechend dem ungleichen Verhältnis von fähigen zu durchschnittlichen 
Programmierern dürfte die Softwarequalität in der Praxis ausfallen.

> Smart Pointer sind die Antwort auf Memory Leaks.

Manchmal löst eine Sprache nur Probleme, die man ohne sie nicht hätte :)

von Nop (Gast)


Lesenswert?

Mikro 7. schrieb:
> Smart Pointer sind die Antwort auf Memory Leaks.

Habe ich embedded nie, weil ich alleine schon wegen 
Speicherfragmentierung sowieso keine dynamische Allozierung nutze. Wo 
nichts alloziert wird, kann auch keine Deallozierung vergessen werden.

von Nop (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Mit C++ kann man ein Niveau erreichen, was fast an plattform-Neutralität
> grenzt.

Dazu muß man eine vernünftige Schichten-Architektur haben, aber das hat 
mit der Programmiersprache nichts zu tun, und dafür brauche ich auch 
kein OOP.

So als Beispiel.. unter Linux auf x86 entwickelt, Zielplattform 
Mikrocontroller ohne Betriebssystem. In C.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

rmu schrieb:
> Was soll da konkret "undefiniert" sein, was in C nicht "undefiniert"
> ist?

 Bei der Vererbung habe ich aufgehört weiterzulesen...


> Der Lachkrampf gibt sich eventuell von selbst wenn man sich weniger
> oberflächlich mit dem Thema beschäftigt, eventuell geht einem dann auch
> ein Licht auf.

 Von Licht oder Dunkelheit mal abgesehen - das, was man bei uC von C++
 gebrauchen kann, hat der C auch.
 Und plain C wird auch ständig verbessert, da steht die Behauptung mit
 der Codegrösse auch nicht.
 Und was mir der Compiler wegoptimiert oder wie der eine bestimmte
 Aufgabe ausführt, ob zuerst A oder B ausgeführt wird, will ich aber
 genau vorgeben und nicht dem Compiler überlassen.
 C als Sprache ist schon furchtbar genug, aber eine Sprache die auf
 C aufbaut und noch komplizierter ist - nein, nicht für mich und
 bestimmt nicht für uC...

 Obwohl, ich beschäftige mich meist mit Industriesteuerungen, da wird
 in Echtzeit gearbeitet und jede us zählt und kann schon zuviel sein.
 Es hat mich (vor etwa 7 Jahren) etwa 2 Wochen Zeit gekostet, um einen
 Programm zu schreiben wo ich einfach mit Häckchen alles auswählen kann
 - von uC und Timern bis zum Interrupts und Peripherie (mit zugehörigen
 Bibliotheken gleich eingebunden, natürlich). Das Gerüst für einen
 Programm ist damit in weniger als 1 Minute fertig.
 Die Daten werden aus XML für entsprechenden Prozessor ausgelesen - ich
 brauche mich um neue Typen und neue Bezeichnungen nicht zu kümmern.
 Wer auch nur einmal stundenlang zwischen Programm und DaBla geschielt
 hat, weiss wovon ich rede.
 Welche Vorteile hat der C++ gegenüber C in dieser Beziehung bei uC ?
 Wie gesagt, für Windows mit mehr als 4GHz, Unmengen von RAM und keiner
 Notwendigkeit auf irgendetwas in Echtzeit zu reagieren, mag das sicher
 gehen, aber bei uC bestimmt nicht.

 P.S.
 Kann mich nicht mehr genau erinnern wer das gesagt hat, aber in etwa:
 Mit C kann man sich ganz leicht ins Bein schiessen, mit C++ ist das
 nicht so einfach aber wenn es passiert, ist gleich das ganze Bein
 weggeschossen...

 P.P.S.
 Wenn der TO dieses in PC-Programmierung gepostet hätte, wurde ich
 mich gar nicht melden - da ist es witzlos, die offensichtlichen
 Vorteile von C++ zu bestreiten.

von Mikro 7. (mikro77)


Lesenswert?

Vincent Samos schrieb:
> Die Anwendung immer komplexerer abstrakter Sprachen ist eine Medaille
> mit zwei Seiten: Was sich mit sinnvoller Verknüpfung zahlloser Features
> hinterher an Zeit sparen ließe mußte vorab erstmal zur Beherrschung der
> Sprache investiert werden:

Ist das eine Tautologie? Sicherlich sollte man immer (!) Aufwand und 
Nutzen im professionellen Umfeld abschätzen.

> Mikro 7. schrieb:
> ...
> Entsprechend dem ungleichen Verhältnis von fähigen zu durchschnittlichen
> Programmierern dürfte die Softwarequalität in der Praxis ausfallen.

Da bin ich neugierig: Wie ist denn das Verhältnis von fähigen zu 
durchschnittlichen Programmierern? Belastbare Quelle? ;-)

>> Smart Pointer sind die Antwort auf Memory Leaks.
>
> Manchmal löst eine Sprache nur Probleme, die man ohne sie nicht hätte :)

Eine der schönen Sachen an C/++ ist, dass man machen kann was man will. 
Sogar performanten Code, wie in keiner anderen Hochsprache. Allerdings 
gibt es auch Fallstricke. Macht das C/++ jetzt gut oder böse?! /Rhetorik 
off

von Vincent Samos (Gast)


Lesenswert?

Mikro 7. schrieb:
> Vincent Samos schrieb:
> Die Anwendung immer komplexerer abstrakter Sprachen ist eine Medaille
> mit zwei Seiten: Was sich mit sinnvoller Verknüpfung zahlloser Features
> hinterher an Zeit sparen ließe mußte vorab erstmal zur Beherrschung der
> Sprache investiert werden:
>
> Ist das eine Tautologie?

Nein. Das bedeutet, daß die Verwendung von C++ gegenüber einfacheren 
Sprachen nicht per se Zeit sparen muß.

> Da bin ich neugierig: Wie ist denn das Verhältnis von fähigen zu
> durchschnittlichen Programmierern? Belastbare Quelle? ;-)

C++ fordert für gleiche oder bessere Ergebnisse mehr Knowhow. Das 
haben erfahrungsgemäß wenigere :)

> Eine der schönen Sachen an C/++ ist, dass man machen kann was man will.

Das sollte eigentlich jede Sprache gewährleisten.

> Sogar performanten Code, wie in keiner anderen Hochsprache.

Dazu hätte ich gern nähere Infos...

> Allerdings
> gibt es auch Fallstricke. Macht das C/++ jetzt gut oder böse?!

Nein. Komplizierter.

von Sheeva P. (sheevaplug)


Lesenswert?

Artur S. schrieb:
> Artur S. schrieb:
>> Sebastian V. schrieb:
>>> Schon allein wegen so "einfachen" Sachen wie Funktionsüberladungen würde
>>> ich C++ jederzeit vorziehen.
>>
>> Sicher. Mit einem fetten ARM ist man ja heutzutage auf der sicheren
>> Seite.
>
> Mit meiner Bemerkung ging es mir um "würde ich C++ jederzeit vorziehen".
> Das kann man sich so absolut behauptet erst mit einem gut ausgestatteten
> Controller erlauben.

Nö, das geht auch auf einem Tiny13 ganz prima. Und den willst Du doch 
wohl sicher nicht als "gut ausgestattet" bezeichnen, oder?

von Sheeva P. (sheevaplug)


Lesenswert?

Findelkind schrieb:
> Torsten R. schrieb:
>> Es gibt Unmengen von features in C++, die
>
> alle zu erlernen und richtig anzuwenden sind!
> Zum Glück brauchte bislang keines meiner Projekte diese Hirnakrobatik
> aus dem Elfenbeinturm.

C++ kann nichts dafür, daß es Dich überfordert.

von Sheeva P. (sheevaplug)


Lesenswert?

Marc V. schrieb:
> Natürlich erzeugt der C++ wahrscheinlich
> effizienteren Code als der Programierer - nur gilt das eben nur für
> diese unnützen Funktionen und Features, die kein normaler Mensch jemals
> bei einem 8-bit AVR oder PIC brauchen wird-

Weißt Du, es geht gar nicht darum, ob man C++ braucht. Es geht darum, ob 
es einem die Arbeit leichter macht -- und das tut es, sogar ziemlich 
gut.

von Max (Gast)


Lesenswert?

Sheeva P. schrieb:
> Nö, das geht auch auf einem Tiny13 ganz prima.

Mit solchen leeren Behauptungen tät ich mich auch nur tiefnachts aus der 
Deckung trauen :)

von Sheeva P. (sheevaplug)


Lesenswert?

Max schrieb:
> Sheeva P. schrieb:
>> Nö, das geht auch auf einem Tiny13 ganz prima.
>
> Mit solchen leeren Behauptungen tät ich mich auch nur tiefnachts aus der
> Deckung trauen :)

Keine Sorge, das mach' ich auch tagsüber. Schließlich weiß ich, daß 
meine Aussage vor allem eines nicht ist: nämlich "leer". ;-)

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Hallo Achim,

Achim S. schrieb:
> Beispiele für effizienter?

ein gerne zitiertes Beispiel ist qsort() vs. std::sort(). qsort() nimmt 
das Sortierkriterium immer als function pointer, und der Aufruf des 
Sortierkriteriums ist von daher schlechter durch inlining zu entfernen. 
std::sort() ist ein template und kennt daher den exakten Typen des 
Sortierkriteriums und wenn der dann eben kein function pointer ist, dann 
hängt das Sortierkriteriums ganz fest am Typen und der compiler kann das 
Sortierkriteriums inlinen.

In einer Library eines Chip-Herstellers habe ich letzte Woche eine 
Funktion gesehen, die aus einer gegebenen Eingangs- und Ausgangsfrequenz 
3 Parameter für eine PLL ermittelt. Die Implementierung ist eine 3-fach 
geschachtelte Schleife, die über alle Bereiche jedes Parameters iteriert 
und guckt ob eine Kombination passt. Diese Funktion wird üblicherweise 
exakt einmal mit immer den gleichen Parametern aufgerufen und liefert 
auch immer das selbe Ergebnis.

In C++ kannst Du diese Funktion zur Compile-zeit ausführen lassen und im 
Code liegen dann nur die ermittelten Parameter der PLL.

mfg Torsten

von Nop (Gast)


Lesenswert?

Sheeva P. schrieb:
> C++ kann nichts dafür, daß es Dich überfordert.

Niemand versteht C++ (vollständig), dazu ist es, STL und Boost 
eingerechnet, viel zu umfangreich. Nichtmal Stroustrup.

Das Gefährliche sind dann C++-Programmierer, die die zahlreichen 
Features zwar anwenden können und deswegen irrtümlich glauben, sie 
hätten das verstanden, aber nicht im Detail wissen, was hinter der 
Compilermagic wirklich vor sich geht.

Die sind der Grund für Torvalds legendären Rant bezüglich Git und C, daß 
allein schon C++-Programmierer fernzuhalten ein Grund für C sei. Damit 
waren nicht die Könner gemeint, sondern die viel zahlreicheren 
Legoprogrammierer.

von Nop (Gast)


Lesenswert?

Torsten R. schrieb:
> Die Implementierung ist eine 3-fach
> geschachtelte Schleife, die über alle Bereiche jedes Parameters iteriert
> und guckt ob eine Kombination passt.

Daß C einen hirnlosen Algorithmus nicht in Konstanten umzuwandeln kann, 
ist kein Argument für C++, sondern gegen den hirnlosen Algorithmus.

Echt mal, eine dreifach verschachtelte Schleife mit Rumprobieren aller 
Möglichkeiten ist doch die bedingungslose Kapitulation des 
Programmierers vor dem Problem.

von nicht"Gast" (Gast)


Lesenswert?

Nop schrieb:
> Echt mal, eine dreifach verschachtelte Schleife mit Rumprobieren aller
> Möglichkeiten ist doch die bedingungslose Kapitulation des
> Programmierers vor dem Problem.

Würde mal sagen nicht Zwangsweise. Wenn du drei Unbekannte aus 2 
gegebenen Werten berechnen musst, kannst du dich auf den Kopf stellen. 
Du wirst kaum einen Alorithmus jenseits von BruteForce finden, der das 
berechnet.

Ich denke mal die Alternativen zu den drei Schleifen sind deutlich 
aufwendiger und damit Fehleranfälliger und schwerer zu verstehen.

 Außerdem, wenn der Compiler das eh ausrechnet, ist der nutzen dem 
Aufwand gegenüber doch angemessen.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Nop schrieb:

> Echt mal, eine dreifach verschachtelte Schleife mit Rumprobieren aller
> Möglichkeiten ist doch die bedingungslose Kapitulation des
> Programmierers vor dem Problem.

Das ist nicht der Punkt. Selbst wenn Du einen "besseren" Algorithmus 
findest, wird der im Bezug auf Speicherverbrauch und Laufzeit deutlich 
schlechter sein, als das Laden des PLL-Konfigurationsregister mit einer 
Konstanten.

von Strubi (Gast)


Lesenswert?

Meine Güte, und sie sind nicht totzukriegen.

Mal wieder die Klassiker bringen:

1) Wer guten Code schreiben will, muss verstehen, was hinten rausfällt, 
spätestens, wenn er's debuggen muss
2) Wer somit gut C++ schreiben will, muss C vollständig 
beherrschen/verstehen. Spätestens an dem Punkt entscheidet sich:
a) Wohlfühl-Programmierer
b) Ergebnisorientierter Programmierer

Letzterer kriegt typischerweise in der Industrie den Auftrag.

Auch für einen uC gilt das Konzept eines robusten/kompakten Kernels 
(oder gerade da...)
Das kann man schon in C++ schreiben (wollen).

Nur:
- new ist verboten (malloc aber auch)
- Exceptions sind verboten (stack unwinding auf uC...)
- STL nur noch bedingt zu geniessen
- und die Liste lässt sich beliebig fortsetzen

Da bleibt dann von den C++-Schmankerl nicht mehr so viel übrig, im 
Gegenteil, es verkompliziert.
Das sind ein paar Gründe, warum alle namhaften Kernel nach wie vor in C 
geschrieben sind. Auch wenn Herr Torvalds nicht immer Recht hat: Hier 
hat er's :-)

von rmu (Gast)


Lesenswert?

Achim S. schrieb:
>> In C++ lässt sich ohne weiteres Code erstellen, der effizienter als
>> äquivalenter C-Code läuft, dabei kürzer und weniger fehleranfällig ist.
>
> Beispiele für effizienter?

Als Beispiel für Code der in C++ effizienter realsierbar wäre führe ich 
die STM HAL-Libs an, da nimmt man ja an, dass das von Profis die ihr 
Geschäft verstehen gemacht wurden.

Wenn man äquivalenten Code mit modernen C++ Techniken implementiert 
kommt in Summe ein kleineres Programm (Codesize) heraus, vor allem 
deswegen, weil der C++-Compiler viele der Laufzeit-Checks auf NULL etc. 
schon zur Compile-Zeit analysieren und daher (weg-)optimieren kann, 
genauso ist es grad bei ARM oft sinnvoll, kurze Funktionen inline 
einzubinden. Ein Funktionsaufruf kostet auch Platz.

Das Ausfüllen und Herumschicken dieser riesigen Initialisier-Structs 
etc. würde man sich auch grossteils sparen.

Makros zur Definition von Registern und Hardware würde man durch 
passende Templates und dazupassende Traits ersetzen, dann kommts nicht 
mehr vor, dass man in ein RO-Register reinschreibt, weil sich der Code 
gar nicht übersetzen lässt.

Wenn man sich auf Exceptions einlässt kann man die Fehlerbehandlung dort 
machen wo sie Sinn macht, und kann sich das stoische Abfragen von 
Rückgabewerten auf Fehlerwerte sparen. Kann sich auszahlen, muss aber 
nicht. In C könnte man ähnliches mit setjmp/longjmp erreichen, hätte 
aber mehr overhead und gleichzeitig würde alles recht unübersichtlich 
und Fehleranfällig. Exceptions haben mit GCC-ARM keinen 
Laufzeit-Overhead, d.h. der Code "zwischen" der Stelle wo geworfen und 
dort wo gefangen wird ist nicht irgendwie speziell oder am 
Exception-Mechanismus irgendwie beteiligt.

C++ Mechanismen garantieren, dass Destruktoren lokaler Objekte 
ausgeführt werden, egal wie man den Kontext verlässt, was extrem 
praktisch für Locks oder Interrupt-Sperren ist, da kann man einfach 
nicht vergessen, etwas wieder freizugeben.

etc...

von nicht"Gast" (Gast)


Lesenswert?

Strubi schrieb:
> 2) Wer somit gut C++ schreiben will, muss C vollständig
> beherrschen/verstehen.

Wozu? Das musst du mal näher ausführen. Wenn ich in C++ programmieren 
möchte, muss ich erst mall C++ verstehen. Was soll mir eine andere 
Programmiersprache bringen.
Im gegenteil, die meisten "Umsteiger" tun sich schwer damit, C außen vor 
zu lassen und dann kommt ein furchtbarer Mischmasch raus.

Strubi schrieb:
> - new ist verboten (malloc aber auch)
> - Exceptions sind verboten (stack unwinding auf uC...)
> - STL nur noch bedingt zu geniessen
> - und die Liste lässt sich beliebig fortsetzen

Auf jeden Fall bleiben Typsicherheit, Templates und Funktionsoverloading 
über. Das reicht mir schon um C++ vorzuziehen.

von rmu (Gast)


Lesenswert?

Marc V. schrieb:
> P.S.
>  Kann mich nicht mehr genau erinnern wer das gesagt hat, aber in etwa:
>  Mit C kann man sich ganz leicht ins Bein schiessen, mit C++ ist das
>  nicht so einfach aber wenn es passiert, ist gleich das ganze Bein
>  weggeschossen...

Mir sind auch schon einige Steuerungen untergekommen, meistens deswegen, 
weil nach einem Compilerwechsel (C) nichts mehr ging. Meistens hat sich 
herausgestellt, dass sich irgendwo eine Routine auf eine bestimmte 
Variante eines undefinierten C-Konstrukts verhalten hat, die beim 
neueren Compiler halt je nach Optimierungsflags sich anders verhält. 
(Das Ergebnis einer undefinierten Aktion darf in C von allem und nichts 
oder auch von der Mondphase abhängen).

Das betraf auch immer Codestellen, die man in C++ komplett anders 
realisiert hätte. ("Generische" Datenstrukturen, Filter, ...)

von rmu (Gast)


Lesenswert?

Strubi schrieb:
> Nur:
> - new ist verboten (malloc aber auch)
new impliziert nicht dass Speicher dynamisch verwaltet wird. placement 
new.

> - Exceptions sind verboten (stack unwinding auf uC...)
geht auf ARM Cortex M0 vorzüglich

> - STL nur noch bedingt zu geniessen

Die iostreams muss man sich sparen, der Rest ist schon brauchbar. 
Manches könnte zwar besser gelöst sein (Allocatoren), aber std::arrays 
sind um einiges angenehmer als nackte Pointer.

> - und die Liste lässt sich beliebig fortsetzen
alles überholte Vorstellungen

> Da bleibt dann von den C++-Schmankerl nicht mehr so viel übrig, im
> Gegenteil, es verkompliziert.
> Das sind ein paar Gründe, warum alle namhaften Kernel nach wie vor in C
> geschrieben sind. Auch wenn Herr Torvalds nicht immer Recht hat: Hier
> hat er's :-)

Das ist historisch bedingt. 1-2 Kernel-Versionen waren mit g++ zu 
kompilieren, der Versuch wurde aber wieder aufgegeben, weil der Compiler 
damals (in den 90ern) zu buggy war.

Windows NT Kern und Abkömmlinge sind auch großteils in C++ geschrieben 
AFAIK, und das fällt auch unter "namhafter Kern" selbst wenn man kein 
Windows-Fan ist.

Der Linux Kernel ist auch vom Organisatorischen her vermutlich nicht für 
C++ geeignet, da man konstant herumstreiten würde/müsste, welches Subset 
von C++ verwendet werden kann/darf. Typische µC-Projekte sind um 
Größenordnungen überschaubarer als der Linux-Kern.

von Test (Gast)


Lesenswert?

Sebastian V. schrieb:
> Da C++ bis auf wenige Ausnahmen auch alle Features von C enhält und dazu
> noch einen Haufen neuer Features, ist C++ deutlich mächtiger (und
> komplizierter). Wenn man weiß wie man mit den neuen Features umgeht und
> welche davon auch für Mikrocontroller geeignet sind dann sehe ich in der
> Verwendung von C++ auf Mikrocontrollern eigentlich nur Vorteile. Wobei
> jetzt auch wieder einige Leute behaupten werden, dass nur das "erste" C
> nach K&R (oder Assembler) das einzig Wahre ist.

Endlich mal jemand mit Ahnung! @TO: Nimm dir das genau so zu Herzen!

von Wilhelm M. (wimalopaan)


Lesenswert?

Und es gibt ein paar ganz einfache Dinge in C++, die einem das Leben auf 
der untersten Ebene leichter machen. Dazu zähle ich auch:

- user-defined-literals, etwa 1_ms oder 43_us oder 42_MHz und die 
Operatoren dafür

- binary-literals, etwa 0b01000101

- Dezimaltrenner: etwa uint32_t x = 1'000'000;

- uniform-initialization (ohne narrowing)

- std::array, std::optional (man braucht keine STL dafür, das hat man 
sich ganz schnell selbst gemacht!)

Das macht das Schreiben angenehmer ... und die Laufzeit leidet nicht.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

Torsten R. schrieb:

> Das ist nicht der Punkt. Selbst wenn Du einen "besseren" Algorithmus
> findest, wird der im Bezug auf Speicherverbrauch und Laufzeit deutlich
> schlechter sein, als das Laden des PLL-Konfigurationsregister mit einer
> Konstanten.

Nö. In C nehme ich dafür Brain 1.0, lese das Handbuch, definiere einen 
gültigen Satz an Parametern und gut. Hatte ich neulich für ein Projekt 
mit fünf einstellbaren Taktfrequenzen und ich glaub 5 PLL-Parametern pro 
Frequenz, dazu natürlich noch voltage scaling, Flash-Waitstates und 
Caches an/aus.

Dann nimmt man eine Funktion, der man diese ganzen Parameter übergibt 
(wo der ganze Registerkrams dann gemacht wird), und eine andere, die man 
als API aufruft, mit nem Enum der gewünschten Systemfrequenz. Die ist 
dann im Wesentlichen ein Switch-Case, dessen Zweck es ist, 
Code-Duplikation der eigentliche Einstellfunktion zu vermeiden.

Andererseits ist der Vorteil an diesem Schleifen-Ansatz mit C++ 
natürlich schon nicht zu leugnen:

- man braucht kein Hirn benutzen (darf man nicht unterschätzen).
- der Compiler entfernt den hirnlosen Bloat, so daß der Kunde nicht 
merkt, daß man nicht denkt.
- und das Beste zum Schluß: Wenn man diesen Ansatz konsequent befolgt, 
kann man leicht Compilierzeiten im Stundenbereich erzeugen. Profis 
dosieren das allerdings gerade soweit, daß ein Compile-Run genug 
aufgebläht wird für ein, zwei Postings bei µC.net, aber nicht soweit, 
daß man noch andere sinnvolle Sachen dazwischen tun könnte.

So, ich könnt dazu noch mehr schreiben, aber der Compiler ist gerade 
fertig.

von nicht"Gast" (Gast)


Lesenswert?

Nop schrieb:
> Nö. In C nehme ich dafür Brain 1.0, lese das Handbuch,

Genau, und weil Brain 1.0 ja bekanntlich keinerlei Bugs und 
Seiteneffekte aufweist, versucht man in der Praxis gewöhnlich diesen 
Faktor so weit wie nur irgend Möglich zu begrenzen.

von Nop (Gast)


Lesenswert?

Ach ja, in C geht das natürlich auch, braucht man nur ein geeignetes 
Buildscript.

Man nimmt sich dazu einfach ein Headerfile, wo die gewünschten Zielwerte 
drinstehen, welche man im Buildscript (vor dem Compiler-Run) mit einem 
Perlscript ausliest. Die Berechnungen macht man dann in Perl, und fügt 
die Ergebnisse denn autogeneriert aus dem Script heraus dem Headerfile 
hinzu. Danach erst wird der Compiler aufgerufen.

Das hat den Vorteil, daß man dabei nicht auf langweilige Sachen wie 
relativ simple Schleifeniterationen begrenzt ist, sondern man kann 
dieses Verfahren auch z.B. zum Invertieren von größeren Matrizen 
benutzen, oder für numerische Integration, das näherungsweise Lösen von 
Differentialgleichungen oder ähnliche Späße. Trotzdem wird der C-Code 
nicht aufgebläht. Genial, oder?

Außerdem muß man dann als C-Programmierer nicht mehr neidisch auf die 
Build-Zeiten der C++-Kollegen schielen.

von nicht"Gast" (Gast)


Lesenswert?

Nop schrieb:
> Ach ja, in C geht das natürlich auch, braucht man nur ein
> geeignetes
> Buildscript.
>
> Man nimmt sich dazu einfach ein Headerfile, wo die gewünschten Zielwerte
> drinstehen, welche man im Buildscript (vor dem Compiler-Run) mit einem
> Perlscript ausliest. Die Berechnungen macht man dann in Perl, und fügt
> die Ergebnisse denn autogeneriert aus dem Script heraus dem Headerfile
> hinzu. Danach erst wird der Compiler aufgerufen.
>
> Das hat den Vorteil, daß man dabei nicht auf langweilige Sachen wie
> relativ simple Schleifeniterationen begrenzt ist, sondern man kann
> dieses Verfahren auch z.B. zum Invertieren von größeren Matrizen
> benutzen, oder für numerische Integration, das näherungsweise Lösen von
> Differentialgleichungen oder ähnliche Späße. Trotzdem wird der C-Code
> nicht aufgebläht. Genial, oder?
>
> Außerdem muß man dann als C-Programmierer nicht mehr neidisch auf die
> Build-Zeiten der C++-Kollegen schielen.

Troll?

du willst also eine andere Programmiersprachen nutzen, um deine Werte 
auszurechen und willst das auch noch als Feature verkaufen?

Wenn du denktst, dass der Compiler nur einfache Schleifen optimieren 
kanns, liegst du falsch.

von Di P. (drpepper) Benutzerseite


Lesenswert?

Ein wichtiges Thema ist auch, dass es für µC von den Herstellern (afaik) 
keine C++-Bibliotheken gibt. Sich mit C++ an die C-Libs anzukoppeln ist 
bezüglich des Programmierstils immer ein bisschen zwittrig, aber dennoch 
möglich.

Für Tipps für brauchbare HALs in C++ wäre ich dankbar :)

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

nicht"Gast" schrieb:
> Troll?

Naja komm, wer hat denn angefangen mit einer verschachtelten 
Rumprobierschleife?! Und das dann auch noch als Feature zu verkaufen, 
daß der Compiler so einen Unsinn covern kann. Die Buildzeiten werden bei 
einem größeren Projekt dann dementsprechend ausfallen, und somit auch 
die Turnaroundzeiten. Die sind bei compilierten Sprachen ohnehin schon 
deutlich größer als bei Scriptsprachen, da muß man den Buildprozeß nicht 
auch noch künstlich aufblähen.

Aber wenn man schon auf einen aufgeblähten Buildprozeß steht, dann kann 
man auch gleich mit Scripten rumsauen. Ganz im Sinne von "don't 
re-invent the wheel" wären dann z.B. Matlabscripte für Numerikkrams eine 
"gute" Idee.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Nop schrieb:
> Naja komm, wer hat denn angefangen mit einer verschachtelten
> Rumprobierschleife?! Und das dann auch noch als Feature zu verkaufen,
> daß der Compiler so einen Unsinn covern kann. Die Buildzeiten werden bei
> einem größeren Projekt dann dementsprechend ausfallen, und somit auch
> die Turnaroundzeiten.

Üblich ist, dass nur die sourcen neu übersetzt werden, die sich geändert 
haben. Und seinen Quarz ändert man üblicherweise nicht laufend. Die 
Compile-Zeiten für einen kompletten rebuild spielen eine untergeordnete 
Rolle. Und wie kommst Du darauf, dass ein Perl-Interpreter schneller 
gestartet ist und den Algorithmus ausgeführt hat, als ein C++ compiler, 
der eh schon läuft?

von Nop (Gast)


Lesenswert?

> Üblich ist, dass nur die sourcen neu übersetzt werden, die sich geändert
> haben. Und seinen Quarz ändert man üblicherweise nicht laufend.

Üblich ist es, daß man mal ins Datenblatt guckt und schlichtweg einen 
Satz von PLL-Werten einmal hernimmt, so wie oben geschildert. Zumal man 
das dann ohnehin noch kapselt, wenn man zur Laufzeit verschiedene 
Taktungen braucht, und dann ist es auch nicht mit der PLL getan, sondern 
Waitstates und voltage scaling kommen auch noch hinzu. Kann man ja ne 
fünffach verschachtelte Schleife nehmen. Ach ja, gerne auch sechsfach, 
auf Cortex-M4 sind es ja schon vier PLL-Parameter.

> Compile-Zeiten für einen kompletten rebuild spielen eine untergeordnete
> Rolle.

Die Einstellung dahinter schon, denn genau derselbe Unsinn wird sich 
dann auch in anderen Dateien abspielen.

> Und wie kommst Du darauf, dass ein Perl-Interpreter schneller
> gestartet ist und den Algorithmus ausgeführt hat, als ein C++ compiler,
> der eh schon läuft?

Wieso schnell? Die Buildzeiten sind Leuten mit so einer Mentalität doch 
ohnehin völlig egal. Mit einem Script kann man halt noch wesentlich 
vielseitiger Zeit verschwenden, ohne daß das im Binary bemerkbar wird. 
Genau das war ja gerade als tolles Feature genannt worden.

Wirklich spaßig wird das übrigens, wenn diese Leute mal an ernsthafte 
Software gesetzt werden. Na das gibt dann aber lange Gesichter, wenn in 
den Vorschriften steht, daß Compiler-Optimierungen nicht gestattet sind.

von Nop (Gast)


Lesenswert?

Übrigens, egal wie beknackt eine Idee ist, es gibt Leute, die machen 
das. Insofern ist das dann nicht einmal getrollt.

In dem Fall mit Scripten erstmal Quelltext aufbereiten. Bei libopencm3 
muß man allen Ernstes Python installiert haben zum Build, weil ein Teil 
der Quelltexte mit Python-Scripten generiert wird. oO

von Rüdiger Asche (Gast)


Lesenswert?

Um mal zur Ursprungsfrage zurückzukommen:

Ja es geht, auch ohne große Einbußen, wenn man auf gewisse features wie 
SEH oder statische Objekte verzichtet*. Ob es sinnvoll ist, hängt vom 
Einsatzgebiet ab. Wo sich die Problemstellung gut objektorientiert 
abbilden läßt (z.B. in komplexeren Zutrittskontrollsystemen, bei denen 
Dinge wie Türen und Leser programmatisch repräsentiert werden können), 
kann es enorm helfen. Wo "nur" relativ maschinennah gearbeitet wird 
(z.B. Messfühlerdatenpumpen), ist es eher optional.

C++ kann darüber hinaus helfen, gewisse Standardfehlern in C zu 
vermeiden. Hier ist ein fast schon triviales beispiel (Pseudocode):

class MutexOp
{
    private:
        osSpecificMutexHandle m_Mutex;
    public:
        MutexOp(osSpecificMutexHandle p_Mutex)
            {m_Mutex = p_Mutex;osSpecificClaimMutex()};
        ~MutexOp(void) {osSpecificReleaseMutex()};
}

Wer dann also zu schützenden Block in die Deklaration

{
    MutexOp(anExistingMutex);
    // zu schützender Code
}

einwickelt, wird nicht in die Falle tappen, einen Funktionsausstieg ohne 
Abgeben des Mutex zu verbraten (weil C++ garantiert, daß der Konstruktur 
beim Eintreten in den scope aufgerufen wird und der Destruktor bei jedem 
Ausstieg aus dem scope). Mit ähnlichen Mitteln lassen sich eine gewisse 
Klasse von Speicherlecks vermeiden.

*Eines der Probleme mit SEH ist, dass es Zusatzsegmente anlegt, die 
einem das Speicherlayout verbiegen. Das Problem mit statisch angelegten 
Objekten ist, dass der Konstruktur vom Laufzeitcode sehr früh aufgerufen 
wird, was bei Embedded Systemen heisst, dass das System mglw. noch nicht 
vollständig initialisert ist.

Wir haben bei einem Kunden ein mäßig komplexes System unter C++ mit 
verschiedenen Middlewaresuiten seit vielen jahren im Einsatz, und ich 
kann mit Sicherheit sagen, daß die Einkapslungsmechanismen eine Menge 
Fehler vermieden haben, die unter C sicherlich aufgetreten wären.

von Sheeva P. (sheevaplug)


Lesenswert?

Nop schrieb:
> Sheeva P. schrieb:
>> C++ kann nichts dafür, daß es Dich überfordert.
>
> Niemand versteht C++ (vollständig), dazu ist es, STL und Boost
> eingerechnet, viel zu umfangreich. Nichtmal Stroustrup.

Quatsch. C++ und die STL sind zwar zweifellos umfangreicher als C, aber 
bei Weitem nicht so riesig, daß man sie nicht verstehen kann. Andere 
Entwickler bekommen das ja auch hin.

Was Boost angeht, ist das eine Sammlung von Bibliotheken und Frameworks, 
die kein Entwickler komplett beherrschen muß. Man sucht sich heraus, was 
man braucht, und benutzt es, genauso wie bei allen anderen Bibliotheken 
aus Drittquellen. Der einzige Unterschied ist, daß die Boost-Libs in 
einer Sammlung vorliegen und nicht von diversen Drittanbietern 
zusammengesucht werden müssen.

von Sheeva P. (sheevaplug)


Lesenswert?

Strubi schrieb:
> Auch für einen uC gilt das Konzept eines robusten/kompakten Kernels
> (oder gerade da...)
> Das kann man schon in C++ schreiben (wollen).
>
> Nur:
> - new ist verboten (malloc aber auch)
> - Exceptions sind verboten (stack unwinding auf uC...)
> - STL nur noch bedingt zu geniessen
> - und die Liste lässt sich beliebig fortsetzen

Nein, läßt sie sich nicht, eigentlich fehlt nur dynamisches Dispatching.

> Da bleibt dann von den C++-Schmankerl nicht mehr so viel übrig, im
> Gegenteil, es verkompliziert.

Ach Gottchen, Du suchst Dir ein paar wenige Features von C++ heraus und 
behauptest dann einfach mal, ohne diese Features sei C++ nutzlos und 
würde die Sache verkomplizieren. Aber Datenkapselung, Polymorphie, 
Vererbung und Templates funktionieren auch auf kleinen uCs wunderbar und 
machen viele Dinge wesentlich einfacher, sicherer und robuster.

von Strubi (Gast)


Lesenswert?

Aargh.
Das schlimmste an diesen immer wieder aufkeimenden 
C++-auf-uC-Bullshit-Bingos ist jeweils, dass sich ohne Ende Frickler zu 
Wort melden, die im Prinzip für ihr kleines eigenes 
Wohlfühl-HAL-Framework Recht haben mögen, aber oft die Realität in den 
Kollaborativen verkennen - oder, dass eine Deadline, 
Robustheitskriterien und Kostenrahmen einzuhalten sind und es nicht 
erwünscht ist, sich zu verzetteln.
Dazu kommen Aspekte der Portabilität, Wartbarkeit und Standardisierung, 
die bei C++ einfach "a fucking mess" ist. Das spart nach meiner 
Statistik keine Zeit, im Gegenteil.

Ich habe absolut nichts gegen C++ (au contraire, ich nutze es ausgiebig) 
- sofern ein vernünftiges Framework vorliegt und man von gewissen 
Features absieht, die einfach in manchen Kontexten "broken by design" 
sind (wie z.B. exceptions in einem RT-Kernel).

Ergo gilt Linus' rant betr. Kernel heute noch, das hat nichts mit 
Compiler bugs zu tun. Die Relität sieht so aus, dass die meisten 
Programmierer oft nicht wissen, was sie da eigentlich tun und mit 
grossen Augen ihr Standardsätzchen abspulen, wenn sie den resultierenden 
Assemblercode zu Gesicht bekommen: Assembler macht doch heute keiner 
mehr.
Spätestens dann ist ein netter Hinweis auf die crt0.S oder SIMD-Mathlib 
fällig... Dennoch muss dann der Müll erst mal aufgeräumt werden und dann 
gehen genau solche Diskussionen wie hier los.

Fakt ist, dass man noch immer in C die grösstmögliche (und portable!) 
Kontrolle über den generierten Code hat und mit geeigneten Tools 
(Rational Rose, lint, valgrind, etc.) Schwachstellen im Vorfeld 
effizient genug auffindet. Bei einem robusten Kernel ist diese 
"Verbosity" gewünscht und gewollt. Spätestens dann, wenn Fehlerszenarien 
per In-Circuit debuggt werden müssen, oder coverage fällig wird.
Da ist es manchmal hilfreich, wenn ein Superset ("++") einer Sprache 
einfach von vornherein ausgeklammert wird.

Und das Beispiel Windows NT hätte man besser nicht als repräsentatives 
Pro für ein C++-Kernel genannt... (ich sage nur: Scheduler).

Auf einer darüberliegenden Schicht, insbesondere in einer geschützten 
Umgebung, macht C++ Sinn, sofern man eine gewisse Komplexität im 
OO-Sinne verringern kann. Ich sehe nur keinen Sinn in Einzeilern, die a 
la Boost eine Menge unnützen Code generieren.

Was Kollaborativen in der C++-Domäne angeht, kann man sich immer 
wunderbar streiten. Als Fan von Bibliothekskonzepten geoutet: die 
meisten kompakten Libraries, die auch auf einem uC brauchbar sind, sind 
nun mal in C geschrieben.
Das ist aber die klassische Meinung der *nix/Opensource-Affinen, im 
Firmenumfeld mag eine ganz andere Religion gelten (und auch 
gerechtfertigt sein).

von Wilhelm M. (wimalopaan)


Lesenswert?

Also Leute, ich verstehe überhaupt gar nicht, was diese Aufregung soll. 
Schreibt doch Euren Code in C und übersetzt ihn mit einem C++-Compiler. 
Und dann sucht Ihr Euch ein paar C++-features raus, die Euch lohnenswert 
erscheinen. Der eine macht eben nur ganz zaghafte Versuche: vielleicht 
verwendet er dann das erste mal in seinem Leben ad-hoc-Polymorphie (aka 
Funktionsüberladung) oder erkennt die wundersame Welt von constexpr 
gegenüber dem Präprozessor. Oder auch nur user-defined-literals und 
binary-literals. Der nächste macht sich ggf. auf in Richtung 
parametrische Polymorphy (aka templates). Es geht doch alles unter einem 
Dach.

Es ist doch keine Entscheidung von C oder C++, sondern eigentlich nur, 
welche der Sprachmerkmale ich schon verstehe, als sinnvoll erachte und 
dann auch nutzen möchte. Jedenfalls würde ich mir ein Forum wünschen, wo 
man über echte Designaspekte diskutieren kann, und nicht die eine 
Fraktion die andere niedermacht, weil man sich unverstanden fühlt oder 
glaubt, alles besser zu wissen.

von Carl D. (jcw2)


Lesenswert?

Wilhelm M. schrieb:
> Also Leute, ich verstehe überhaupt gar nicht, was diese Aufregung soll.
> Schreibt doch Euren Code in C und übersetzt ihn mit einem C++-Compiler.

Aber Wilhelm, das geht doch nicht. Sobald man ein großes C oder cpp (*) 
als Source-File-Extension eintippt, explodiert der Rechner wegen 
Code-Bloat.
zudem versteht man dann auch schlagartig den selbst geschriebenen Code 
nicht mehr. Alles viel zu gefährlich.

;-))


*je nach OS. Ogott, nächste Falle ...

von dasrotemopped (Gast)


Lesenswert?

einfach mal bei Google CppCon 2016 eingeben für alle die, die des 
Englischen mächtig sind.

meine 2 Lieblingsvideos:
https://youtu.be/D7Sd8A6_fYU

https://youtu.be/zBkNBP00wJE

Besonders der 2. Link ist beeindruckend.
Commodore C64 in C++ ohne Overhead programmieren.

Das Ergebnis für mich lautet nur, egal ob C oder C++, werde besser mit 
der Sprache, die du schon kannst. Kannst du noch keine von beiden, wirf 
ne Münze, eine bessere Begründung für die eine oder andere Sprache gibt 
es nicht.

Gruß,

dasrotemopped.

von dasrotemopped (Gast)


Angehängte Dateien:

Lesenswert?

oder man folgt dem Trend, den der C++ Experte festgestellt hat.

von Stefan F. (Gast)


Lesenswert?

Warum dem Trend nachlaufen, sind wir Lemminge?

von Ralf M. M. (ramime)


Lesenswert?

Wilhelm M. schrieb:
> Jedenfalls würde ich mir ein Forum wünschen, wo
> man über echte Designaspekte diskutieren kann, und nicht die eine
> Fraktion die andere niedermacht, weil man sich unverstanden fühlt oder
> glaubt, alles besser zu wissen.

Danke! Du schreibst mir aus der Seele.

von Wilhelm M. (wimalopaan)


Lesenswert?

dasrotemopped schrieb:
> einfach mal bei Google CppCon 2016 eingeben für alle die, die des
> Englischen mächtig sind.
>
> meine 2 Lieblingsvideos:
> https://youtu.be/D7Sd8A6_fYU
>
> https://youtu.be/zBkNBP00wJE
>

Ja, die habe ich natürlich auch gesehen, wobei Dan am Ende seines talks 
auf ein paar wichtige nicht-technische Dinge eingeht. Und das betrifft 
den Umgang mit neuen bzw. anderen Sprachmerkmalen. Die Erkenntnis kommt 
nur, wenn man einmal das Gefühl gehabt hat, etwas anders machen zu 
müssen, und man dann auch Hilfe erhalten hat, weil man sich auf Neues 
eingelassen hat!

Aus den gleichen Gründen wie Dan habe ich deswegen in diesem Thread wie 
auch in den anderen Threads zum Thema erst mal die vermeintlich kleinen 
Dinge hervorgehoben (s.o.). In den Zusammenhang gehören natürlich auch 
domänen-spezifische Datentypen und const-correctness. Und mein 
Lieblingszitat von Scott: "Ein Interface muss leicht richtig und schwer 
falsch zu benutzen sein"!
Dazu gehört auch RAII (s.a. obiges Beispiel mit dem mutex-locker). Herb 
Sutter sagte mal auf die Frage, was sein liebstes syntaktisches 
Konstrukt in C++ sei: "}"

Zum Experimentieren ist übrigens

http://gcc.godbolt.org/

wirklich gut geeignet. Wer dort allerdings den neueren avr-gcc (> 6.2) 
drin haben möchte, muss sich das lokal aufsetzen.

VG

von rmu (Gast)


Lesenswert?

Strubi schrieb:
> Aargh.
> Das schlimmste an diesen immer wieder aufkeimenden
> C++-auf-uC-Bullshit-Bingos ist
[viel blabla gelöscht]
> im Gegenteil.

Dass die Diskussion ausarten wird war mir auch gleich klar. Was sich in 
der Praxis wie auszahlt oder ausgeht hängt hauptsächlich an den 
Ausführenden. Wenn man Code für verschiedene Architekturen generisch 
schreiben will kommt so der so auch mit C ein "ad-hoc-HAL" heraus, einen 
Standard gibts da ja nicht.

> Ich habe absolut nichts gegen C++ (au contraire, ich nutze es ausgiebig)
> - sofern ein vernünftiges Framework vorliegt und man von gewissen
> Features absieht, die einfach in manchen Kontexten "broken by design"
> sind (wie z.B. exceptions in einem RT-Kernel).

exceptions sind für Ausnahmen gedacht, die sollten in einem RT-Kernel im 
realtime-zeitkritiscen Teil per Definition nicht passieren. Ausserhalb 
sind die unkritisch, aber man muss halt genau im Aug haben was man tut.

> Ergo gilt Linus' rant betr. Kernel heute noch, das hat nichts mit
> Compiler bugs zu tun. Die Relität sieht so aus, dass die meisten
> Programmierer oft nicht wissen, was sie da eigentlich tun und mit
> grossen Augen ihr Standardsätzchen abspulen, wenn sie den resultierenden
> Assemblercode zu Gesicht bekommen: Assembler macht doch heute keiner
> mehr.

Wer bei einem µC Projekt NICHT standardmässig das asm-listing erzeugt 
und regelmässig kontrolliert bzw. auf Codesize anschaut macht eh was 
falsch. Hat ja nichts mit C oder C++ zu tun.

IIRC hat Linus/x nicht vorgehabt spezielle C++ features zu verwenden, 
man wollte nur die bessere Typprüfung ausnutzen.

> Spätestens dann, wenn Fehlerszenarien
> per In-Circuit debuggt werden müssen, oder coverage fällig wird.
> Da ist es manchmal hilfreich, wenn ein Superset ("++") einer Sprache
> einfach von vornherein ausgeklammert wird.

geht genauso mit C++, was soll da ein Problem darstellen. Genauso kann 
man sagen, dass sich viele Problemtypen mit C++ schon statisch vermeiden 
lassen, die man unter C umständlich dynamisch (zur Laufzeit) debuggen 
muss. Valgrind und ähnliche Memory-Debugger werden auf µC nicht 
funktionieren, da fehlt die nötige Hardware (MMU, RAM).

Rational Rose würde ich wie einen Nuklear-Störfall behandeln, und am 
besten gleich mitsamt Hardware in einen Salzstock einlagern. Ich kenn 
das nur als UML "Tool", und UML macht mit C gleich nochmal halb so wenig 
Sinn. Eventuell Rational Purify gemeint? Kann man das auf µC verwenden?

> Und das Beispiel Windows NT hätte man besser nicht als repräsentatives
> Pro für ein C++-Kernel genannt... (ich sage nur: Scheduler).

war kein Pro, sondern nur ein Ist.

> Auf einer darüberliegenden Schicht, insbesondere in einer geschützten
> Umgebung, macht C++ Sinn, sofern man eine gewisse Komplexität im
> OO-Sinne verringern kann. Ich sehe nur keinen Sinn in Einzeilern, die a
> la Boost eine Menge unnützen Code generieren.
>
> Was Kollaborativen in der C++-Domäne angeht, kann man sich immer
> wunderbar streiten. Als Fan von Bibliothekskonzepten geoutet: die
> meisten kompakten Libraries, die auch auf einem uC brauchbar sind, sind
> nun mal in C geschrieben.
> Das ist aber die klassische Meinung der *nix/Opensource-Affinen, im
> Firmenumfeld mag eine ganz andere Religion gelten (und auch
> gerechtfertigt sein).

Firmenreligion ist oft "VAX-kompatibles K&R C, das haben wir immer schon 
so gemacht", Revisionskontrolle per kopieren und ummurxen, das ist auf 
keinen Fall produktiver als C++ mit boost etc...

So das wars. Meine Popcorn sind alle. Viel Spass noch.

von Strubi (Gast)


Lesenswert?

Moin,

rmu schrieb:

> exceptions sind für Ausnahmen gedacht, die sollten in einem RT-Kernel im
> realtime-zeitkritiscen Teil per Definition nicht passieren. Ausserhalb
> sind die unkritisch, aber man muss halt genau im Aug haben was man tut.

Das Kritische wird oft erst bei der coverage augenscheinlich, also wenn 
man für jede Kombination von Ausnahmen (Fehlercodes) eine entsprechendes 
Handling nachweisen muss. Da gibt's unterschiedliche Philosophien, meine 
ist, dass Fehler dort behandelt werden, wo sie passieren. Jegliche 
Propagation von unkontrolliertem Fehler-Handling auf unterschiedliche 
Funktionslayer ist ein Albtraum. Bequem als schneller Hack, aber im 
Reg'test fliegt's in der Fehlersimulation durch. Dann gibt es eine Latte 
weiterer Probleme beim Stack-Unwinding auf Kernel-Level, da ist C++ 
schlicht "broken by design". Gibt da nen netten Artikel zu:
http://www.lighterra.com/papers/exceptionsharmful/

Bei Python und Java sind Exceptions legitim, da das "Kernel" schon eine 
atomar arbeitende Stack-Maschine bereitstellt. Also: Nicht grundsätzlich 
sind Exceptions böse.

> geht genauso mit C++, was soll da ein Problem darstellen. Genauso kann
> man sagen, dass sich viele Problemtypen mit C++ schon statisch vermeiden
> lassen, die man unter C umständlich dynamisch (zur Laufzeit) debuggen
> muss. Valgrind und ähnliche Memory-Debugger werden auf µC nicht
> funktionieren, da fehlt die nötige Hardware (MMU, RAM).
>

Das stimmt. Aber deinen Code kannst du ja schon mal im Trockentest unter 
deinem Lieblings-OS durch valgrind jagen bzw. im qemu durchemulieren, 
bevor du ihn auf den uC portierst.

> Rational Rose würde ich wie einen Nuklear-Störfall behandeln, und am
> besten gleich mitsamt Hardware in einen Salzstock einlagern. Ich kenn
> das nur als UML "Tool", und UML macht mit C gleich nochmal halb so wenig
> Sinn. Eventuell Rational Purify gemeint? Kann man das auf µC verwenden?

Kann sein dass das Purify war, aber Regressionstests wurden mit Rose 
entwickelt, wenn ich mich nicht täusche. Konnte für unsern Zweck aber 
schliesslich auch nicht mehr als Python und gcov, zumindest vor ca. 15 
Jahren. Mit dem obigen "Trockentest"-Ansatz zur Code-Verifikation kann 
man's sicher auch für nen uC anwenden, aber das wäre für mich auch eine 
Art der Verzettelung..

> Firmenreligion ist oft "VAX-kompatibles K&R C, das haben wir immer schon
> so gemacht", Revisionskontrolle per kopieren und ummurxen, das ist auf
> keinen Fall produktiver als C++ mit boost etc...

Für sowas gibts ja git, was ja auch in C geschrieben ist. Der Rest 
erledigt sich heutzutage ja per SCRUM. Sorry für den Scherz.
So einige Firmen dürften nach Experimenten mit wunderschönen 
akademischen Ansätzen wieder zu den Klassikern zurückgekehrt sein, weil 
ebendiese Ansätze eine Menge Geld gekostet haben, spätestens als das 
Zeug im Feld jemandem um die Ohren flog - soweit meine bescheidene 
Meinung als SW-Feuerlöscher.

von Alexander S. (alesi)


Lesenswert?

Passend zum Titel dieses Threads gibt es auf www.heise.de gerade den
Artikel "Schlanke Embeded-Entwicklung mit Small C++"
https://www.heise.de/developer/artikel/Schlanke-Embeded-Entwicklung-mit-Small-C-3576516.html

von Wilhelm M. (wimalopaan)


Lesenswert?

Leider hat der Author nicht bedacht, dass
1
    constexpr uint8_t volatile *portReg() {
2
        return reinterpret_cast<uint8_t volatile *>(port);
3
    }

niemals als constexpr ausgewertet werden kann / darf, da dort ein 
reinterpret_cast enthalten ist

Man kann also etwa
1
    constexpr auto x = p.portReg();
nicht schreiben (wenn man mal testweise portReg() public macht).

von Sebastian V. (sebi_s)


Lesenswert?

Strubi schrieb:
> Da gibt's unterschiedliche Philosophien, meine
> ist, dass Fehler dort behandelt werden, wo sie passieren. Jegliche
> Propagation von unkontrolliertem Fehler-Handling auf unterschiedliche
> Funktionslayer ist ein Albtraum.

Das ist ja interessant. Warum ist da bloß früher keiner drauf gekommen? 
Irgendwas mit dem ich kommunizieren will antwortet nicht oder schickt 
Müll? Kein Problem! Dann werden einfach irgendwelche Antworten erfunden! 
Der Benutzer hat schwachsinnige Parameter übergeben? Einfach in 
irgendwas umwandeln das Sinn macht. Dann kann man sich ja auch 
Fehlercodes als Rückgabewerte sparen weil einfach keine Funktion mehr 
fehlschlagen kann!

von Robin.R. (Gast)


Lesenswert?

Manche programmieren ihre Controller sogar mit Arduino und nicht mit 
diesen altmodischen legacy erbschad Sprachen! ;-)


... Immer diese all halbjährlich wiederkehrende Diskussion zwischen 
Experten die ihre Fahrradschuppenfarbe bevorzugen.

von Christopher J. (christopher_j23)


Lesenswert?

Wilhelm M. schrieb:
> Leider hat der Author nicht bedacht, dass
>     constexpr uint8_t volatile *portReg() {
>         return reinterpret_cast<uint8_t volatile *>(port);
>     }
>
> niemals als constexpr ausgewertet werden kann / darf, da dort ein
> reinterpret_cast enthalten ist

GCC inkl. Version 7.0 scheint es trotzdem zu fressen. Ist zwar als Bug 
markiert aber konsequent unterbunden wird es vom Compiler nicht. 
Außerdem sitzt der Autor im Standardkomitee und muss es ja somit wissen 
(oder doch nicht ?). Das er sich mit dem C-Präprozessor nicht versteht 
kann ich gut verstehen. Bei folgendem Makro würde ich als Compiler auch 
meckern:
1
#define ledCycle(onMs, offMs)   \
2
        (ledOn(),               \
3
         _delay_ms(onMs),       \
4
         ledOff(),              \
5
         _delay_ms(offMs))

von Wilhelm M. (wimalopaan)


Lesenswert?

Christopher J. schrieb:
> Wilhelm M. schrieb:
>> Leider hat der Author nicht bedacht, dass
>>     constexpr uint8_t volatile *portReg() {
>>         return reinterpret_cast<uint8_t volatile *>(port);
>>     }
>>
>> niemals als constexpr ausgewertet werden kann / darf, da dort ein
>> reinterpret_cast enthalten ist
>
> GCC inkl. Version 7.0 scheint es trotzdem zu fressen. Ist zwar als Bug
> markiert aber konsequent unterbunden wird es vom Compiler nicht.

Bei mir mit gcc aus git gibt es schon einen Fehler (wie in meinem 
Beispiel geschrieben). Und das ist dann auch das richtige Verhalten ...

: Bearbeitet durch User
von Christopher J. (christopher_j23)


Lesenswert?

Ich hatte es selber mit Version 7.0 nicht ausprobiert und von daher kann 
es gut sein, dass der Compiler es doch nicht ohne weiteres frisst. Die 
Info war aus dem GCC Bugzilla: 
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49171#c13

Bei GCC Version 4.7 funktioniert es aber noch reibungslos bei mir. Ist 
aber zugegebenermaßen auch hoffnungslos veraltet. Eventuell läuft beim 
Autor auch noch eine etwas ältere Version ;)

von Wilhelm M. (wimalopaan)


Lesenswert?

In dem Beispiel des Authors wird die Elementfunktion ja auch nicht in 
einem constexpr-Ausdruck ausgewertet, deswegen geht's es. Will man aber 
wie oben ja schon geschrieben, das Funktionsergebnis in einem 
constexpr-Ausdruck etwa einer constexpr-Variablen Definition verwenden, 
dann schlägt es - wie mindestens ab C++14 verlangt - fehl.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.