Hallo Welche Programmiersprache sollte man heutzutage auf Mikrocontrollern mit viel Flash und RAM verwenden? Ich kenne nur C, C++ und C#. Ich denke, auf dem PC sollte man mit C# oder Java am schnellsten und einfachsten seine GUI Applikationen umsetzen können. Wer hier, in Zeiten der Rechner Kraftpakete mit hoher Taktung, zu C++ oder C greift, der sollte sich fragen, ob er zu viel Freizeit hat. Machbar ist alles auch mit Assembler. Wie sieht es auf der Mikrocontroller Ebene aus? Welche Gründe gibt es hier für den Einsatz von C oder C++. C ist im Vergleich zu C++ eine Untermenge von C++ und im Vergleich dazu relativ einfach und schnell gelernt und beherrscht. Meiner Meinung nach. C++ ist in Anwendung all seiner Möglichkeiten doch recht schwer zu verstehen. Dennoch finde ich ein, von den sprachlichen Möglichkeiten, einfach gehaltenes C++ Programm für Mikrocontroller vorteilhaft gegenüber der Entwicklung mit C. Wenn jedoch sämtliche sprachlichen Stilmittel von C++ genutzt werden, so finde ich, verschwindet dieser Vorteil wieder, da diese nur wenige C++ Programmierer ohne Probleme verstehen. Was denkt ihr über den Einsatz von C++ auf Mikrocontrollern?
Schorsch schrieb: > Wenn jedoch sämtliche sprachlichen Stilmittel von C++ > genutzt werden, so finde ich, verschwindet dieser Vorteil wieder, da > diese nur wenige C++ Programmierer ohne Probleme verstehen. C++ - Programmierer verstehen die allermeisten sprachlichen Stilmittel von C++, sonst wären es keine C++ Programmierer. Insofern wäre es für dich sinnvoll, zunächst mal C++ zu lernen, bevor du über dessen Einsatz sinnierst. Oliver
Schorsch schrieb: > Ich denke, auf dem PC sollte man mit C# oder Java am schnellsten und > einfachsten seine GUI Applikationen umsetzen können. Wer hier, in Zeiten > der Rechner Kraftpakete mit hoher Taktung, zu C++ oder C greift, der > sollte sich fragen, ob er zu viel Freizeit hat. Wer hier von Kraftpaketen und Java spricht, muß sich fragen lassen, weshalb er Ressourcen und Zeit seiner Kunden vergeudet. Der Programmierer ist zu faul, anständig zu programmieren und hunderte oder tausende seiner Kunden oder nee, Opfer brauchen mehr Speicher und warten unnötig lange auf das Rechenergebnis. Wenn ich Alternativen habe, fliegt Javascheiß direkt wieder raus.
Schorsch schrieb: > Ich denke, auf dem PC sollte man mit C# oder Java am schnellsten und > einfachsten seine GUI Applikationen umsetzen können. Wer hier, in Zeiten > der Rechner Kraftpakete mit hoher Taktung, zu C++ oder C greift, der > sollte sich fragen, ob er zu viel Freizeit hat. Also ich empfinde C# als reine Monokultur (Mono unter Linux ist nicht so der Hit....)... und bei Java musst Du immer die VM mit rumschleppen, aktuell halten usw... Für C++ gibt es viele nette GUI-Frameworks, große und kleine... und einige bieten den Vorteil dabei auch noch unter SEHR vielen Plattformen zu laufen, die Anwendung muss dann einmalige für die Zielplattform kompiliert werden und fertig....
Beitrag #5033526 wurde von einem Moderator gelöscht.
Schorsch schrieb: > Ich denke, auf dem PC sollte man mit C# oder Java am schnellsten und > einfachsten seine GUI Applikationen umsetzen können. Wer hier, in Zeiten > der Rechner Kraftpakete mit hoher Taktung, zu C++ oder C greift, der > sollte sich fragen, ob er zu viel Freizeit hat. Das ist, mit Verlaub, ziemlicher Unsinn. Viele, wenn nicht gar die meisten modernen GUI-Programme sind in C++ implementiert. Die Entwicklereffizienz von Programmiersprachen mit automatischer Speicherverwaltung / Garbage Collection wie Java oder eben C# ist nicht wesentlich höher als die von C++, schon vor vielen Jahren -- lange vor C++11ff, als die STL noch in ihren Kinderschuhen steckte und RAII noch eher selten verwendet wurde -- lag die Entwicklereffizienz von Java-Entwicklern in einer Untersuchung des renommierten Dr.Dobb's Magazine gerade einmal etwa 12% höher als jene von C++-Entwicklern. Obendrein ist die automatische Speicherverwaltung gerade in Programmen, die größere Datenmengen mit engen zeitlichen Vorgaben verarbeiten müssen, ein ziemlich zweischneidiges Schwert, wie ich aus eigener leidvoller Erfahrung weiß. Häufig muß man in die Optimierung des Garbage Collectors dieselbe, in manchen Fällen sogar ein Vielfaches der in der Entwicklung gesparten Zeit investieren. Insofern ist die Entwicklereffizienz von C++ wesentlich besser, als Du zu glauben scheinst. Dank moderner C-Frameworks wie GTK kann man auch in C sehr schnell und effizient GUI-Applikationen entwickeln, und die größten Aufwände bei der Entwicklung von GUI-Software sind eh nicht im Coding -- ok, vielleicht bei Hobbyisten, aber nicht im professionellen Umfeld. > Wie sieht es auf der Mikrocontroller Ebene aus? > > Welche Gründe gibt es hier für den Einsatz von C oder C++. > > C ist im Vergleich zu C++ eine Untermenge von C++ und im Vergleich dazu > relativ einfach und schnell gelernt und beherrscht. Meiner Meinung nach. Meiner Meinung nach nicht. C hat viele subtile Fein- und Eigenheiten, die Anfänger regelmäßig überfordern. "Relativ einfach und schnell gelernt und beherrscht" trifft heute am Ehesten auf moderne Skriptsprachen wie Python, Ruby, Lua oder Perl zu, aber bislang jedenfalls auf keine kompilierte und typsichere Programmiersprache -- jedenfalls keine, die mir bekannt ist. > C++ ist in Anwendung all seiner Möglichkeiten doch recht schwer zu > verstehen. > Dennoch finde ich ein, von den sprachlichen Möglichkeiten, einfach > gehaltenes C++ Programm für Mikrocontroller vorteilhaft gegenüber der > Entwicklung mit C. Wenn jedoch sämtliche sprachlichen Stilmittel von C++ > genutzt werden, so finde ich, verschwindet dieser Vorteil wieder, da > diese nur wenige C++ Programmierer ohne Probleme verstehen. > > Was denkt ihr über den Einsatz von C++ auf Mikrocontrollern? Naja, die meisten Möglichkeiten von C++ sind in so begrenzten Umgebungen wie Mikrocontrollern ohnehin nicht besonders sinnvoll. Zum Beispiel eine dynamische Speicherallokation ist auf Mikrocontrollern eher selten, auch dynamisches Binden wird dort nicht oft verwendet. Aber der Clou ist: auch ein Programm, das nur ein einziges C++-Features nutzt, ist damit ein valides C++-Programm. Datenkapselung und Vererbung zum Beispiel können auch auf kleinsten 8-Bittern sinnvoll und ohne irgendwelche Nachteile verwendet werden. Schon vermeintliche Kleinigkeiten wie Scoped Enums sind ein guter und ausreichender Grund für C++ statt C. Dein "Argument" gegen C++, daß nur wenige C++-Entwickler "sämtliche sprachlichen Stilmittel ohne Probleme verstehen" halte ich im Übrigen für unsinnig. Modernes C++ ist ziemlich einfach, in vielerlei Hinsicht sogar wesentlich einfacher als C; schon auf PCs verwendet kaum ein Entwickler "sämtliche sprachlichen Stilmittel" von C++. Dies gilt erst Recht auf Mikrocontrollern, wo es wesentlich wichtiger ist zu wissen, welche der Sprachmittel dort sinnvoll und ohne übermäßige Belastung der meistens knappen Ressourcen angewendet werden können. Aber auch abseits dessen ist es ein unsinniges Argument, daß nur wenige C++-Entwickler "sämtliche sprachlichen Stilmittel" verstünden. Das ist höchstens ein Argument gegen die betreffenden Entwickler, jedoch keines gegen eine Programmiersprachen -- schon gar nicht, wenn es um eine der am Weitesten verwendeten Programmiersprachen geht. Vielleicht gilt es ja für Dich, daß Du nicht "sämtliche sprachlichen Stilmittel" beherrschst, aber von sich auf andere zu schließen, ist erstens stillos und zweitens ganz sicher kein valides Sachargument. ;-)
Oliver S. schrieb: > Schorsch schrieb: >> Wenn jedoch sämtliche sprachlichen Stilmittel von C++ >> genutzt werden, so finde ich, verschwindet dieser Vorteil wieder, da >> diese nur wenige C++ Programmierer ohne Probleme verstehen. > > C++ - Programmierer verstehen die allermeisten sprachlichen Stilmittel > von C++, sonst wären es keine C++ Programmierer. Ich melde mal Zweifel an :D
Ich verwende der besseren Selbstdokumentation wegen gerne ein Pascal auf Controllern. Bisher ein E-Lab Pascal auf AVR, nun ein Mikroe Pascal auf PIC32. Die Dialekte sind hinreichend aehnlich, dass ein Protokol schnell uebertragen ist. Sonst ist portabilitaet kein Thema. Etwas, was auf einem PC laeuft, wird nie auf einem controller laufen, was ich auf einem PIC32 laufen lassen wird weder auf PC noch auf AVR portiert. Aeh ja. auf dem PC lass ich Delphi laufen.
Der Nuller schrieb: > Etwas, was auf einem PC laeuft, wird nie auf einem controller laufen, > was ich auf einem PIC32 laufen lassen wird weder auf PC noch auf AVR > portiert. Meinst du. Aber nur solange die Plattform nicht gewechselt werden muss. Mikrocontroller Software kann man übrigens auch auf dem PC testen und Debuggen, wenn entsprechende abstrahiert wurde. Es gibt auch Anwendungen, in denen die gleiche software auf Mikrocontroller und PC verwendet wird (ti nspire).
Der Nuller schrieb: > der besseren Selbstdokumentation Was meinst Du damit? Und warum den uC-Code nicht am PC testen und laufen lassen?
Mit C# kann man fehlerfreiere, mit C schnellere Programme schreiben als mit C++ aber man schreibt ungern alles alleine und die meisten Bibliotheken gibt es derzeit für C++.
Man kann C nicht als Untermenge von C++ bezeichnen, denn es gibt bei manchen Konstrukten subtile Unterschiede ... Meine (persönliche) Antwort: nur C++! Was C ggf. interessant machen könnte, sind nicht-standardisierte Erweiterungen wie memory-sections __flash oder auch saturierende arith. Typen und FixedPoint. Aber: das ist eigentlich wieder ein Argument für C++, denn die o.g. Dinge hat man schnell in C++ realisiert bzw. nimmt eine entsprechende Bibliothek und hat damit wieder vollständig konformen Code. Natürlich muss man die richtigen Werkzeuge aus dem großen Werkzeugkasten C++ auswählen und die nicht angebrachten drin liegen lassen, etwa Heap-Alloc, RTTI, Exceptions, RT-Polymorphie, ... Aber gerade die modernen features von C++ wie etwa variadic-templates, fold-expressions, constexpr, lambdas, etc., etc. machen das Leben auch auf einem µC sehr sehr angenehm (natürlich auch die normalen: templates, sichere Container, ...) Für mich ist die Entscheidung klar!
C# und Java sind einfacher zu lernen und verstehen, ja. C und C++ haben viele Eigenheiten, aber auch viele Vorteile, gerade im Umgang mit Ressourcen. Bei C++ war der Sprung von 98 auf 11 recht gravierend und hat viele Annehmlichkeiten mit sich gebracht. Auf uC verwende ich C, einfach weil ich bereits C++ behersche und auf dem PC überwiegend C++ mit dem Qt Framework. Klar man muß auf mehr achten, aber dennoch hat es bisher sehr wenige Situationen gegeben, in denen ich gerne auf C# umgestiegen wäre.
Welche Programme soll man denn auf dem PC UND auf einem Controller laufen lassen ? Ich finde leider exakt gar keins. Auf einem Controller habe ich auch immer etwas mit Kommunikation, Steuerung, Regelung, Timing, Messung.
:
Bearbeitet durch User
Sapperlot W. schrieb: > Welche Programme soll man denn auf dem PC UND auf einem Controller > laufen lassen ? Ich finde leider exakt gar keins. Protokolle (z.B. CANOpen) lassen sich am PC viel schöner debuggen als auf dem späteren Zielsystem. Oder auch grafische Oberflächen. Wir lassen auch UnitTests für hardwareunabhängige Module auf dem PC laufen. Grundsätzlich läuft alles oberhalb der Hardwareschicht auch auf dem PC um es eben schneller /besser testen und debuggen zu können. > Auf einem Controller habe ich auch immer etwas mit Kommunikation, > Steuerung, Regelung, Timing, Messung. Der hardwareabhängige Teil wird auf dem PC dann entsprechend simuliert. Matthias
Schorsch schrieb: > Hallo > > Welche Programmiersprache sollte man heutzutage auf Mikrocontrollern mit > viel Flash und RAM verwenden? > > Ich kenne nur C, C++ und C#. > Die Fragestellung ist falsch. Mikrocontroller (im Gegensatz zu "All Purpose Computern") werden so für ihre Anwendungsfälle ausgesucht, dass ihre Ressourcen (Flash, RAM, Prozessorgeschwindigkeit, Peripherie) ausreichen, um die Aufgabe zu lösen. Überdimensionierte Controller machen im Embedded Bereich (noch) keinen Sinn, und das wird sich erst dann ändern, wenn die Preisunterschiede zwischen kleinen und grossen Chips so gering sind, dass man sich auch bei grossen Stückzahlen eine x fache Überdimensionierung leisten kann. Das Laufzeitsystem von C#, Java & Co ist dermassen Ressourcenhungrig, dass die Laufzeitunterstützung selbst im Minimalfall um ein Vielfaches grösser ist als der Code, der die eigentliche Aufgabe löst. Von der fehlenden Echtzeitfähigkeit mal ganz abgesehen. Also wirst Du "Mikrocontroller mit viel Flash und RAM" auch nur dort finden, wo das viel Flash und RAM zur Lösung der Aufgabenstellung benötigt wird, und damit sind Java und Konsorten out. C++ ist Anders, solange Du eine Minimaluntermenge benutzt (z.B. auf SEH verzichtest). Da ist der Unterschied zu C kaum messbar, das steht aber an sehr vielen Stellen im Internet zu lesen (s.u.) > > Was denkt ihr über den Einsatz von C++ auf Mikrocontrollern? Wenn Du das wirklich wissen willst, brauchst Du nur die Suchfunktion im Forum zu benutzen. Kaum ein Thema, das breiter und leidenschaftlicher diskutiert worden ist und wird. Aber scheinbar ist noch nicht von Alles Alles geschrieben worden.
Schorsch schrieb: > Hallo > > Welche Programmiersprache sollte man heutzutage auf Mikrocontrollern mit > viel Flash und RAM verwenden? Haskell ist geeignet für µC mit viel Flash und RAM ^^
Sven B. schrieb: >> C++ - Programmierer verstehen die allermeisten sprachlichen Stilmittel >> von C++, sonst wären es keine C++ Programmierer. > > Ich melde mal Zweifel an :D ;) Ursprünglich schrub ich da "alle", aber das hat mich dann selbst nicht überzeugt ;) Oliver
Die Diskussion hatten wir schon oft genug. Ich erwarte nicht, dass dieser Thread irgend eine neue Erkenntnis zutage bringt. Lasst das Thema ruhen, bevor es wieder mit persönlichen Beleidgungen los geht - denn so endet das Thema immer.
Schorsch schrieb: > Wie sieht es auf der Mikrocontroller Ebene aus? Ganz einfach: Speicher ist teuer, Ram ist teur, Taktfrequenz kostet ebenfalls. Dementsprechend wird man damit, zumindest bei Großserienprodukten, möglichst sparsam umgehen. Java, C++ u.dgl. ist dementsprechend out, C ist in... Bei normaler PC-Software wird halt eine CD oder DVD, in hartnäckigen Fällen eine BlueRay, ausgeliefert, da kostet Speicherplatz fast nichts. Für den eigentlichen Computer, inklusive Hardwareupgrades, ist dann der Kunde zuständig.
Schreiber schrieb: > Schorsch schrieb: >> Wie sieht es auf der Mikrocontroller Ebene aus? > > Ganz einfach: > Speicher ist teuer, Ram ist teur, Taktfrequenz kostet ebenfalls. > Dementsprechend wird man damit, zumindest bei Großserienprodukten, > möglichst sparsam umgehen. Java, C++ u.dgl. ist dementsprechend out, C > ist in... Widerspruch: C++ ist keinesfalls laufzeitmäßig "teurer" als C. Das sind alte Mythen, die eigentlich noch nie gestimmt haben, und jetzt erst recht nicht mehr stimmen ...
Wilhelm M. schrieb: > Schreiber schrieb: >> Schorsch schrieb: >>> Wie sieht es auf der Mikrocontroller Ebene aus? >> >> Ganz einfach: >> Speicher ist teuer, Ram ist teur, Taktfrequenz kostet ebenfalls. >> Dementsprechend wird man damit, zumindest bei Großserienprodukten, >> möglichst sparsam umgehen. Java, C++ u.dgl. ist dementsprechend out, C >> ist in... > > Widerspruch: C++ ist keinesfalls laufzeitmäßig "teurer" als C. Das sind > alte Mythen, die eigentlich noch nie gestimmt haben, und jetzt erst > recht nicht mehr stimmen ... ACK. Ich vermute mal, dass "Schreiber" statt C++ C# schreiben wollte. Dann würde auch die Nebeneinanderstellung mit Java Sinn machen. Wie schon mehrfach geschrieben wurde, kann man C++ so nutzen, dass der Footprintunterschied zu C gen 0 geht.
Beitrag #5034468 wurde von einem Moderator gelöscht.
Beitrag #5034558 wurde von einem Moderator gelöscht.
Beitrag #5034574 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Was C ggf. interessant machen könnte, sind nicht-standardisierte > Erweiterungen wie memory-sections __flash oder auch saturierende arith. > Typen und FixedPoint. Das macht aber nicht die Sprache, sondern nur die Compiler interessant, die diese nicht-standardisierten Erweiterungen anbieten. ;-)
Schreiber schrieb: > Speicher ist teuer, Ram ist teur, Taktfrequenz kostet ebenfalls. > Dementsprechend wird man damit, zumindest bei Großserienprodukten, > möglichst sparsam umgehen. Java, C++ u.dgl. ist dementsprechend out, C > ist in... Eigentlich ist C++ "in", einige Menschen haben es nur noch nicht gemerkt. C++ kostet nichts, verbraucht keinen zusätzlichen Speicher, keinen RAM, und keine CPU-Takte im Vergleich zu C, und ist also genauso sparsam wie C -- aber C++ bietet viele Möglichkeiten, um die Organisation und die Wiederverwendbarkeit des Code teilweise erheblich zu verbessern. Das erkennt man aber erst, wenn man über den Schatten der bekannten Vorurteile springt, und C++ einfach mal lernt und praktisch einsetzt.
Sheeva P. schrieb: > Schreiber schrieb: >> Speicher ist teuer, Ram ist teur, Taktfrequenz kostet ebenfalls. >> Dementsprechend wird man damit, zumindest bei Großserienprodukten, >> möglichst sparsam umgehen. Java, C++ u.dgl. ist dementsprechend out, C >> ist in... > > Eigentlich ist C++ "in", einige Menschen haben es nur noch nicht > gemerkt. C++ kostet nichts, verbraucht keinen zusätzlichen Speicher, > keinen RAM, und keine CPU-Takte im Vergleich zu C, und ist also genauso > sparsam wie C -- aber C++ bietet viele Möglichkeiten, um die > Organisation und die Wiederverwendbarkeit des Code teilweise erheblich > zu verbessern. Das erkennt man aber erst, wenn man über den Schatten der > bekannten Vorurteile springt, und C++ einfach mal lernt und praktisch > einsetzt. Leider nein. Laut Dan Saks sinkt die Trendlinie von embedded C++ software, während die von C steigt. Siehe hier: https://www.youtube.com/watch?v=D7Sd8A6_fYU
Sheeva P. schrieb: > Eigentlich ist C++ "in", einige Menschen haben es nur noch nicht > gemerkt. C++ kostet nichts, verbraucht keinen zusätzlichen Speicher, > keinen RAM, und keine CPU-Takte im Vergleich zu C, und ist also genauso > sparsam wie C -- aber C++ bietet viele Möglichkeiten, um die > Organisation und die Wiederverwendbarkeit des Code teilweise erheblich > zu verbessern. Das erkennt man aber erst, wenn man über den Schatten der > bekannten Vorurteile springt, und C++ einfach mal lernt und praktisch > einsetzt. Richtig, diese Vorurteile kommen meiner Erfahrung nach von Anfängern, die irgendwann mal irgendwelche C++ Features unnötig ohne Sinn und Verstand genutzt haben und sich nicht bewusst waren, dass diese an bestimmten Stellen ordentlich Performance kosten können (manche, nicht alle!). Da wird dann z.B. am laufenden Band eine verkettete Liste (std::list) kopiert, d.h. eine neue Liste angelegt, mehrmals Speicher vom Heap angefordert und der Inhalt kopiert. Oder anderes Beispiel: Stringverkettung mit std::string. Und am Ende heult man im Internet rum, dass C++ so viel langsamer ist als C. Der Rest nimmts ungeprüft auf und verbreitet es weiter...
Vincent H. schrieb: > > Leider nein. Laut Dan Saks sinkt die Trendlinie von embedded C++ > software, während die von C steigt. > > Siehe hier: > https://www.youtube.com/watch?v=D7Sd8A6_fYU Sehr guter Vortrag, übrigens nicht der einzige aus der Reihe. Dan Saks sieht aber das Problem, daß Fakten nichts an Überzeugungen ändern können, nicht nur im Enbeded-Entwicklungsbereich. Womit er leider recht behielt. Schön ist auch der Vortrag, der zeigt, wie man mit C++14 Videospiele für dem C64 schreibt. https://www.youtube.com/watch?v=zBkNBP00wJE Wie man z.B. mit constexpr RGB-Farbewerte in C64-Farbwerte wandeln kann. Genauso kann man bei einem AVR bei gegebener Zeit die optimale Kombination aus Prescaler und CompareA-Registerwert ermitteln. Zur Compilezeit. Alternativ frickelt der Moby die Bits von Hand zusammen.
:
Bearbeitet durch User
Sheeva P. schrieb: > Wilhelm M. schrieb: >> Was C ggf. interessant machen könnte, sind nicht-standardisierte >> Erweiterungen wie memory-sections __flash oder auch saturierende arith. >> Typen und FixedPoint. > > Das macht aber nicht die Sprache, sondern nur die Compiler interessant, > die diese nicht-standardisierten Erweiterungen anbieten. ;-) Genau. Und wie ich weiter schrieb, ist das ja wieder ein Argument für C++ ...
Carl D. schrieb: > Vincent H. schrieb: >> >> Leider nein. Laut Dan Saks sinkt die Trendlinie von embedded C++ >> software, während die von C steigt. >> >> Siehe hier: >> https://www.youtube.com/watch?v=D7Sd8A6_fYU > > Sehr guter Vortrag, übrigens nicht der einzige aus der Reihe. Dan Saks > sieht aber das Problem, daß Fakten nichts an Überzeugungen ändern > können, nicht nur im Enbeded-Entwicklungsbereich. Womit er leider recht > behielt. > Schön ist auch der Vortrag, der zeigt, wie man mit C++14 Videospiele für > dem C64 schreibt. > https://www.youtube.com/watch?v=zBkNBP00wJE In einem anderen Beitrag hatte ich einfach mal angefangen, solche interessanten Vorträge, o.ä zu sammeln, damit sich dort jeder informieren kann. Und das nicht ständig diese alten, längst überholten und auch falschen Mythen zitiert werden. Beitrag "Informationen zu C vs C++ / aka Futter für die Diskussion" > Wie man z.B. mit constexpr RGB-Farbewerte in C64-Farbwerte wandeln kann. > Genauso kann man bei einem AVR bei gegebener Zeit die optimale > Kombination aus Prescaler und CompareA-Registerwert ermitteln. Zur > Compilezeit. Alternativ frickelt der Moby die Bits von Hand zusammen. Ja, man kann sehr viel schöne Dinge zur Compilezeit machen: suchen, sortieren, optimieren, ... Dazu habe ich auch schon etliches mal gepostet, aber ich glaube, das hat eigentlich niemand bemerkt. Meistens kommt dann die CPP/C-Fraktion um die Ecke mit irgendwelche grausligen Macros ...
:
Bearbeitet durch User
Vincent H. schrieb: > Leider nein. Laut Dan Saks sinkt die Trendlinie von embedded C++ > software, während die von C steigt. Was auch kein Wunder ist, denn das Hauptproblem von C++ wird mit jedem neuen Standard schlimmer: Der Sprachumfang. Zwar werden neue Sachen eingeführt, die mehr Annehmlichkeiten bringen, aber da in der realen Welt die überwiegende Zahl der Projekte die Erweiterung bestehender Software ist, muß man dann immer mehr Standards beherrschen. Das mag vielleicht noch für reine Coder leistbar sein. Aber embedded ist das Coding vielfach nicht das Entscheidende, sondern Domänenwissen. Deswegen auch z.B. die ganzen E-Ings als SW-Entwickler mit HW-Wissen, und mehr als C geht da einfach nicht. Es sei denn, man macht eine völlige Trennung auf, aber dann hat man im Troubleshooting wieder ein Problem, weil der Systemfachmann dann den Code nicht versteht, während der Coder das Domänenwissen nicht hat. Es wird noch schlimmer, weil C++ so ziemlich alles ermöglicht. Das heißt im Umkehrschluß aber auch, daß es nicht ausreicht, wenn man weiß, welche Dinge man wozu gebrauchen kann, sondern man muß für embedded auch noch wissen, was exakt unter der Haube abläuft. Das ist keine Abstraktion, das ist obfuscation. Sicher, die Experten, die das draufhaben, die haben da kein Problem. Aufgrund der größeren Schwierigkeit, dieses Level mit C++ hinzukriegen im Vergleich zu C, sind diese Leute dann aber auch einfach teurer, ganz besonders wenn sie außerdem auch noch Domänen-Fachleute sind. Das ist kein technisches Problem, sondern ein wirtschaftliches. Selbst Stroustrup gibt das ja zu - mit C schießt man sich in den Fuß (was aber leicht zu beheben ist). Mit C++ schießt man sich seltener, aber dann das ganze Bein ab, und das ist viel schwieriger zu beheben. Was Stroustrup nicht sagt, ist, daß die mäßigen C++-Programmierer sich ähnlich oft ins Bein schießen wie mäßige C-Programmierer sich in den Fuß. Und wieso wird das nicht groß diskutiert? Weil keiner sich traut zuzugeben, ein mäßiger Programmierer zu sein. Besonders dann nicht, wenn die wirklich guten Programmierer den Mund aufmachen. Auch das ist kein technisches Problem, sondern ein soziales. Ja, sicher, wenn man verlinkte Listen in C++ einfach aus dem Regal greifen kann, anstatt die fehlerträchtig und wahrscheinlich auch langsamer selber in C hinzufrickeln, ist das cool. Ich habe aber in 20 Jahren embedded nie eine verlinkte Liste gebraucht, die man nicht genausogut auch mit einem statischen Array hätte machen können. Überhaupt kommt meiner Erfahrung nach die Komplexität embedded, anders als auf dem PC, nicht durch riesige einzelne Software zustande. Sondern die Modularisierung geschieht auf Hardware-Ebene, indem das Systemdesign schon die Blöcke auf unterschiedliche Teilsysteme runterbricht, die dann über geeignete Interfaces kommunizieren. Das wird schon durch Anforderungen an Segregation sowie durch Reaktionszeiten erzwungen. Die Alternative ist natürlich, und auch das sehe ich in der Praxis, daß man 95% von C++ ignoriert und C mit Klassen macht - und statischen Objekten, weil dynamische Speicherverwaltung das System sowieso untestbar macht. Das ist noch ganz übersichtlich nutzbar. Wenn man aber 95% von C++ nicht nutzt, schrumpfen genau dadurch auch die potentiellen Vorteile zusammen, und man muß dauernd aufpassen, daß die Leute nicht mit "oh wir können hier aber dieses und da das Feature noch nutzen" nach und nach eine wilde Migration zu vollem C++ hinlegen. Gab ja mal die Initiative "Embedded C++", die das hätte adressieren sollen, aber die ist irgendwie auch in sich zusammengesackt. Und ja, man kann natürlich bequem z.B. einen UART als Objekt instanzieren, und man kann auch leicht unterschiedliche Klassen für prinzipiell ähnliche Interfaces einfach handhaben. Eleganter als in C jedenfalls. Das sind aber letztlich völlig irrelevante Implementationsdetails. Deswegen sind auch Saks' technische Argumente für C++ nett, aber genauso irrelevant. Und nein, "die sind eben alle komplett doof" ist nicht die Antwort, auch wenn da technisch gesehen was dran ist. Wenn man sachlich korrekte Argumente hat, die trotzdem nicht überzeugen, könnte es aber auch daran liegen, daß man das falsche Problem diskutiert. Wo es allerdings echt aufhört, das ist überall da, wo man eine GUI braucht. Das ist in C der Horror (BTDT), weil die OOP-Unterstützung sehr bescheiden ist.
Nop schrieb: > Vincent H. schrieb: > >> Laut Dan Saks sinkt die Trendlinie von embedded C++ >> software, während die von C steigt. > > Was auch kein Wunder ist, denn das Hauptproblem von C++ wird mit jedem > neuen Standard schlimmer: Der Sprachumfang. Zwar werden neue Sachen > eingeführt, die mehr Annehmlichkeiten bringen, aber da in der realen > Welt die überwiegende Zahl der Projekte die Erweiterung bestehender > Software ist, muß man dann immer mehr Standards beherrschen. Nein. Nur weil man mehr Dinge darf, muß man man nicht mehr Dinge müssen. Mehr Auswahl zu haben ist ein Privileg, kein Hemmnis. Es wurde breits vorher gesagt: jedes Programm, das nur ein einziges C++ Feature benutzt (sei es ein neuer Typ wie bool oder Namespaces oder Überladung eines Funktionsnamens per unterschiedlicher Signatur) ist am Ende ein C++ Programm (auch wenn es sonst zu 99.5% reines C ist) und gehört auf der Waage auf die "C++" Seite. Bis auf ein paar wenige verbohrte C Extremisten dürfte jeder Programmierer derart niedrig hängende Früchte vom C++ Baum mit Vergnügen annehmen, zumal wenn der C++ Compiler in Form des g++ frei Haus kommt. Auf den (beklagenswerten, IMHO) Architekturen, die zwar einen C- aber keinen C++ Compiler haben, mag das natürlich anders aussehen.
Axel S. schrieb: >> Was auch kein Wunder ist, denn das Hauptproblem von C++ wird mit jedem >> neuen Standard schlimmer: Der Sprachumfang. Zwar werden neue Sachen >> eingeführt, die mehr Annehmlichkeiten bringen, aber da in der realen >> Welt die überwiegende Zahl der Projekte die Erweiterung bestehender >> Software ist, muß man dann immer mehr Standards beherrschen. > > Nein. > > Nur weil man mehr Dinge darf, muß man man nicht mehr Dinge müssen. > Mehr Auswahl zu haben ist ein Privileg, kein Hemmnis. Ich bin ein Anhänger von C++, aber die immense Komplexität der Sprache muss man schon als Argument gelten lassen. Wobei es stimmt: die neuen Standards machen vieles sehr viel einfacher und führen vor allem dazu, dass man kein wahnsinnig tiefgreifendes Verständis der alten Features braucht, weil es mit den neuen oft sehr intuitiv anders geht. Insgesamt ist es von Anwenderseite leichter mit C++17 ein bestimmtes Ziel zu erreichen als mit C++03, und darauf kommt es an. > Es wurde breits vorher gesagt: jedes Programm, das nur ein einziges C++ > Feature benutzt (sei es ein neuer Typ wie bool oder Namespaces oder > Überladung eines Funktionsnamens per unterschiedlicher Signatur) ist am > Ende ein C++ Programm (auch wenn es sonst zu 99.5% reines C ist) und > gehört auf der Waage auf die "C++" Seite. Naja. Ein Programm ist ein C++-Programm wenn es gegen die C++ Runtime linkt. Das ist eigentlich zumindest auf Desktop-Systemen relativ einfach.
:
Bearbeitet durch User
Axel S. schrieb: > Nur weil man mehr Dinge darf, muß man man nicht mehr Dinge müssen. > Mehr Auswahl zu haben ist ein Privileg, kein Hemmnis. Siehe Vorposting, darauf bin ich eingegangen. > Es wurde breits vorher gesagt: jedes Programm, das nur ein einziges C++ > Feature benutzt Das ist formal C++, ja, aber ich finde es albern, ein C-Programm mit "bool" als C++ zu werten. Das kann man machen, wenn man Statistiken frisieren will. > zumal wenn der C++ Compiler in Form des g++ frei Haus kommt. http://embeddedgurus.com/stack-overflow/2010/02/is-gcc-a-good-compiler/
Dan Saks: "I'm giving C++ talks to an embedded audience and the curious thing, it is a confession, is I've never built an industrial strength embedded system out of C++." WTF?
> Deswegen auch z.B. die ganzen E-Ings als SW-Entwickler mit HW-Wissen, > und mehr als C geht da einfach nicht. Das ist SEHR richtig. Will nur leider kaum einer verstehen. Dazu kommt noch was anderes. Gerade die Leute in einer Firma die bei komplexen Themen die unabdingbare Erfahrung haben, sind auch bereits alte Saecke. Die wollen einfach keine weitere Programmiersprache lernen und erst recht nicht sowas abstraktes. Dazu kommt noch das im Embedded bereich auch SEHR viel alter Code in C weiter verwendet werden muss. Es ist dann einfacher man macht den Bubis frisch von der Uni klar das sie entweder C lernen und verwenden oder sich nach einen anderen Job umkucken sollten. > Es wird noch schlimmer, weil C++ so ziemlich alles ermöglicht. Das heißt > im Umkehrschluß aber auch, daß es nicht ausreicht, wenn man weiß, welche > Dinge man wozu gebrauchen kann, sondern man muß für embedded auch noch > wissen, was exakt unter der Haube abläuft. Das ist keine Abstraktion, > das ist obfuscation. Auch dem kann ich nur zustimmen. Hilfreich waere vielleicht ein C-- oder einen Compilerswitch der C++ alles verbietet was im Embeddedbereich alles nicht sinnvoll ist. Aehnlich diesen Misra Tools die normalen C ja bereits verschiedenes abgewoehnen. > Und wieso wird das nicht groß diskutiert? Weil keiner sich traut > zuzugeben, ein mäßiger Programmierer zu sein. Oh ja! Da ist sehr richtig. Hinzu kommt noch das es gerade im Programmierbereich viele alte Quereinsteiger gibt die bereits oben in der Nahrungskette angekommen sind. Dem tritt man nicht einfach so gegegen sein virtuelles Schienbein. :-) > Gab ja mal die Initiative "Embedded C++", die das hätte adressieren > sollen, aber die ist irgendwie auch in sich zusammengesackt. Wusste ich noch garnicht das es soetwas gibt. Schade wenn daraus nichts wird. Kannst du mal einen Link liefern? Ich denke auch das es dringend an der Zeit ist C durch was besseres abzuloesen. Aber die normative Kraft des Faktischen verhindert das noch sehr erfolgreich und das wird sicher auch noch 5-10Jahre so bleiben. Olaf
olaf schrieb: >> Deswegen auch z.B. die ganzen E-Ings als SW-Entwickler mit HW-Wissen, >> und mehr als C geht da einfach nicht. > > Das ist SEHR richtig. Will nur leider kaum einer verstehen. Dazu kommt > noch was anderes. Gerade die Leute in einer Firma die bei komplexen > Themen die unabdingbare Erfahrung haben, sind auch bereits alte Saecke. > Die wollen einfach keine weitere Programmiersprache lernen und erst > recht nicht sowas abstraktes. Das ist dann ja eine Bankrott-Erklärung der Embedded-Branche!!! > Dazu kommt noch das im Embedded bereich auch SEHR viel alter Code in C > weiter verwendet werden muss. Es ist dann einfacher man macht den Bubis > frisch von der Uni klar das sie entweder C lernen und verwenden oder > sich nach einen anderen Job umkucken sollten. Auch das halte ich für eine fatale Strategie: man gibt ja auch nicht die Devise aus, nur noch alte µC einzusetzen: 8-Bit ist so schön einfach, man kann den Leuten keine 32-Bit zumuten. >> Und wieso wird das nicht groß diskutiert? Weil keiner sich traut >> zuzugeben, ein mäßiger Programmierer zu sein. Und das wäre dann in einem Unternehmen eine Frage der Personalentwicklung. > Oh ja! Da ist sehr richtig. Hinzu kommt noch das es gerade im > Programmierbereich viele alte Quereinsteiger gibt die bereits oben in > der Nahrungskette angekommen sind. Dem tritt man nicht einfach so > gegegen sein virtuelles Schienbein. :-) Da fällt mir der Handwerkerspruch ein: soll es vernünftig werden oder solls der Chef machen ;-) >> Gab ja mal die Initiative "Embedded C++", die das hätte adressieren >> sollen, aber die ist irgendwie auch in sich zusammengesackt. Ja, weil sie bei old-school C++ stehen geblieben ist. Aber ich denke, dass sich da noch etwas tun wird.
:
Bearbeitet durch User
> Das ist dann ja eine Bankrott-Erklärung der Embedded-Branche!!! Unterschätze nicht, wie schnell junge Leute lernen können. Wenn es wirklich nötig ist, kommen die auch ganz schnell auf die Grundlagen. Für uns (jetzt 40 Jährige) war es damal noch sehr mühsam, Programmieren zu lernen. Man hatte nur sehr begrenzten Zugang zu Literatur und Hardware. Doch heute haben wir das Internet. Vergesst das nicht. > denn das Hauptproblem von C++ wird mit jedem > neuen Standard schlimmer: Der Sprachumfang Dann müsste Java längst tot sein. Es wächst sehr viel schneller, als C++, und ist dennoch eine sehr häufig angewendete Programmiersprache im Enterprise Umfeld. Auch ich meine: man muss ja nicht alles benutzen, was geht.
Schorsch schrieb: > Wie sieht es auf der Mikrocontroller Ebene aus? > > Welche Gründe gibt es hier für den Einsatz von C oder C++. Erstmal das Datenblatt lesen und verstehen!!!!! Denn das würde hier 90% der sinnlosen Fragen der Fragenden selbst beantworten. Viele glauben das man einfach ein paar Bibliotheken zusammen verknüft das man dann programmmieren kann aber spätestens wenn es um Timerfunktionen, Interrupt,ADC's oder einfach nur berechnen geht, fehlts den meisten an Grundlagen. Da hilft auch die Beste Bibliothek nichts!!!! Die Sprache hängt davon ab was du willst und kannst und wieviel Flash man zur Verfügung hat.
Sheeva P. schrieb: > C++ einfach mal lernt Ein Widerspruch in sich. Der Umfang gängiger Lehrbücher spricht Bände. Sven B. schrieb: > aber die immense Komplexität der Sprache > muss man schon als Argument gelten lassen. Im Grunde stranguliert sich die Sprache mit ihrem ausufernden Umfang als Empfehlung für einfache MCs selbst. Die pure Zahl der Möglichkeiten macht es immer schwerer, die optimale = sparsame und performanteste Umsetzung zu finden. Flexibel hat als Kehrseite leider Gottes komplex. Allein die Vorgabe des TO, MCs mit viel Flash und RAM zu betrachten, mildert die Notwendigkeit sparsamer Codierung hier etwas. Da man mit dem 32Bit MC aber gleichzeitig selbst mehr Hardware-Komplexität geliefert bekommt verbietet sich hier, was bei einfachen 8Bittern immer noch und weiter naheliegt: Asm ohne viel administrativen Aufwand in Sprache und Programmiermittel-Setup.
Stefan U. schrieb: >> Das ist dann ja eine Bankrott-Erklärung der Embedded-Branche!!! > > Unterschätze nicht, wie schnell junge Leute lernen können. Wenn es > wirklich nötig ist, kommen die auch ganz schnell auf die Grundlagen. Ich glaube, da hast Du mich falsch verstanden. Ich glaube eher, dass diejenigen, die hier manchmal so gegen C++ wettern, nicht die Zeit oder den Willen haben, über den Tellerrand hinaus zu sehen. Beides ist gleichermaßen schlecht. Eine Firma, die ihren MA nicht die Zeit, etc. gibt, neue Technologien (was auch immer) zu erlernen, ist schlecht beraten. Und MA die nicht den Willen dazu haben, sich weiter zu entwicklen (gerade in einem Unternehmen dieser Branche) sollten ihre Position wechseln. Insgesamt wäre das eine Argumentation nach dem Motto: das haben wir schon immer so gemacht. Und deswegen bleibt es so. Dies ist aber kurzsichtig. Und ich hoffe, dass das dann doch in den meisten Firmen nicht so ist ;-)
:
Bearbeitet durch User
H.J.Gebhardt schrieb: > Sheeva P. schrieb: >> C++ einfach mal lernt > > Ein Widerspruch in sich. > Der Umfang gängiger Lehrbücher spricht Bände. Das Problem vieler Lehrbücher (vor allem aus dem europäischem Raum) ist, das es den Autoren meistens nicht darum geht, dem Lernenden zu helfen, sondern darzustellen, was für ein toller Hecht der Autor ist! Das ist im angloamerikanischen Bereich oft anders (leider sind die Bücher von Bjarne da eine Ausnahme: aber er hatte auch nicht das Ziel, ein Lehrbuch zuschreiben, sondern sein Baby darzustellen).
> Für uns (jetzt 40 Jährige) war es damal noch sehr mühsam, Programmieren > zu lernen. Man hatte nur sehr begrenzten Zugang zu Literatur und > Hardware. Doch heute haben wir das Internet. Vergesst das nicht. Interessanterweise sehe ich den Nachwuchs eher im Nachteil. Das Internet liefert zuviel Ablenkung vom wesentlichen und gleichzeitig ist die Hardware und die Projekte so komplex geworden das sie ein einzelner nicht mehr so eben komplett durchschauen kann. Von Leuten die glauben dann Libaries zusammenzuklauben zu koennen damit alles einfach wird garnicht zu reden. Es fehlt dann oft an Grundlagen um sich im komplexen sicher zu bewegen. > Die Sprache hängt davon ab was du willst und kannst und wieviel Flash > man zur Verfügung hat. Was vielen nicht so klar ist, Effizienz ist bei Embedded sehr viel entscheidender als in anderen Bereichen. Wenn mein Produkt mit Batterie nur halb so lange laeuft wie bei der Konkurrenz bin ich tod. Und wenn man einen Prozessor verwenden muss der eine Nummer leistungsfaehiger ist als notwendig ist dann happert es dieses Jahr an den Bonuszahlungen. .-) Olaf
olaf schrieb: >> Die Sprache hängt davon ab was du willst und kannst und wieviel Flash >> man zur Verfügung hat. > > Was vielen nicht so klar ist, Effizienz ist bei Embedded sehr viel > entscheidender als in anderen Bereichen. Ja, schon, aber... Effizient ist zu 99% davon abhängig ob man geeignete Algorithmen verwendet hat. Was hilft ein Speedup von 3 wenn man alles statt in Java, in ASM geschrieben hat, wenn man mit geeigneteren Algorithmen einen Faktor 20 haben könnte. 73
Wilhelm M. schrieb: > Das ist dann ja eine Bankrott-Erklärung der Embedded-Branche!!! Nein, sondern es ist die Einsicht, daß das Coding gegenüber dem Domänenwissen zweitrangig ist. > Auch das halte ich für eine fatale Strategie: man gibt ja auch nicht die > Devise aus, nur noch alte µC einzusetzen: 8-Bit ist so schön einfach, > man kann den Leuten keine 32-Bit zumuten. Mit C(++) besteht da, abgesehen von ein paar Datentypen, kein wesentlicher Unterschied. > Und das wäre dann in einem Unternehmen eine Frage der > Personalentwicklung. Auf gut deutsch: Geld bezahlen, ohne dafür einen entsprechenden Gegenwert zu bekommen. Mal abgesehen davon, daß OOP-Code anderer Leute auch deutlich schwerer nachzuvollziehen ist. Prozeduralen Code kann man einfach sequentiell lesen. Man muß in C++ nicht OOP machen, aber das ist eines der Hauptfeatures gegenüber C. > Ja, weil sie bei old-school C++ stehen geblieben ist. Aber ich denke, > dass sich da noch etwas tun wird. Nein. Eher wird man die ganze C-Familie hinter sich lassen, und erst recht C++. C++ ist deswegen so absurd, weil es abwärtskompatibel zu C sein mußte. Das war damals korrekt, weil es sich sonst gar nicht hätte etablieren können, aber der Preis war hoch. Wilhelm M. schrieb: > Und MA die nicht den Willen dazu haben, sich weiter zu > entwicklen (gerade in einem Unternehmen dieser Branche) sollten ihre > Position wechseln. Man sollte sich lieber überlegen, ob man diese Arbeit wirklich in C++ stecken will. Besonders vor dem Hintergrund, daß das reine Coding zusehends ausgelagert wird, etwa nach Osteuropa. Zudem ist auch nicht jede neue Technologie tatsächlich sinnvoll, und nur weil sie neu ist, heißt das nicht, daß sie deswegen auch besser wäre. Und dann haben wir da noch die ganz radikale Argumentation vom Schlage Torvalds, daß C allein schon den Vorteil hat, Leute fernzuhalten, die lieber C++ wollen. Klingt polemisch, ist es auch, aber die versachlichte Aussage ist zumindest bedenkenswert: Mehr Abstraktion bedeutet nicht automatisch besser. C hat gegenüber Assembler wegen der Abstraktion viele Vorteile, aber die Dosis macht das Gift. Es ist eine Abwägung. Mit "je mehr Abstraktion, desto besser" holt man sich letztlich "architecture astronauts" an Bord, wie Joel Spolsky das nennt, und genau DIE fernzuhalten ist durchaus eine Idee, besonders embedded. Wenn Leute es total wesentlich finden, daß man einen UART als Objekt instanzieren kann, dann sind das einfach fragwürdige Prioritäten, bzw. "l'art pour l'art".
Hans schrieb: > Effizient ist zu 99% davon abhängig ob man geeignete Algorithmen > verwendet hat. Das ist auch meine Erfahrung. Die eigentliche Entwicklungsarbeit findet vor dem Coden statt. Microoptimierung eines bestehenden Ablaufes bringt wenig bis gar nichts, kostet aber unendlich viel Zeit.
Nop schrieb: > Und dann haben wir da noch die ganz radikale Argumentation vom Schlage > Torvalds, daß C allein schon den Vorteil hat, Leute fernzuhalten, die > lieber C++ wollen. Klingt polemisch, ist es auch, aber die versachlichte > Aussage ist zumindest bedenkenswert: Das drehe ich um: C++ hat den Vorteil, Leute fernzuhalten, die lieber C wollen ;-) > Mehr Abstraktion bedeutet nicht automatisch besser. Es kommt auf die Abstraktionen an, die man gewählt hat. > C hat gegenüber > Assembler wegen der Abstraktion viele Vorteile (s.o.) >, aber die Dosis macht das > Gift. Es ist eine Abwägung. Mit "je mehr Abstraktion, desto besser" es geht nicht um mehr Abstraktion, sondern um bessere Abstraktionen!
H.J.Gebhardt schrieb: > Ein Widerspruch in sich. > Der Umfang gängiger Lehrbücher spricht Bände. > > Im Grunde stranguliert sich die Sprache mit ihrem ausufernden Umfang als > Empfehlung für einfache MCs selbst. Die pure Zahl der Möglichkeiten > macht es immer schwerer, die optimale = sparsame und performanteste > Umsetzung zu finden. Flexibel hat als Kehrseite leider Gottes komplex. > Allein die Vorgabe des TO, MCs mit viel Flash und RAM zu betrachten, > mildert die Notwendigkeit sparsamer Codierung hier etwas. Da man mit dem > 32Bit MC aber gleichzeitig selbst mehr Hardware-Komplexität geliefert > bekommt verbietet sich hier, was bei einfachen 8Bittern immer noch und > weiter naheliegt: Asm ohne viel administrativen Aufwand in Sprache und > Programmiermittel-Setup. Haha viel Geschwurbel und alles zu komplex außer 8-Bit und Assembler, ein klassischer Moby. Ein Blinder spricht von Farben...
Nop schrieb: > Wilhelm M. schrieb: > >> Das ist dann ja eine Bankrott-Erklärung der Embedded-Branche!!! > > Nein, sondern es ist die Einsicht, daß das Coding gegenüber dem > Domänenwissen zweitrangig ist. Wenn man keine besonderen Anforderungen an die Software hat und die so mal nebenbei macht dann ja. Ansonsten nö. Als Softwareentwickler ist man Architekt und Handwerker zugleich. Was ist ein Maurer wert, der sein Handwerk nicht versteht? Nop schrieb: >> Und das wäre dann in einem Unternehmen eine Frage der >> Personalentwicklung. > > Auf gut deutsch: Geld bezahlen, ohne dafür einen entsprechenden > Gegenwert zu bekommen. Mal abgesehen davon, daß OOP-Code anderer Leute > auch deutlich schwerer nachzuvollziehen ist. Prozeduralen Code kann man > einfach sequentiell lesen. Man muß in C++ nicht OOP machen, aber das ist > eines der Hauptfeatures gegenüber C. Also mich reizen ja eher so Features wie Typsicherheit, Referenzen, Templates (generische Datenstrukturen in C sind ein Krampf), constexpr... Nop schrieb: >> Ja, weil sie bei old-school C++ stehen geblieben ist. Aber ich denke, >> dass sich da noch etwas tun wird. > > Nein. Eher wird man die ganze C-Familie hinter sich lassen, und erst > recht C++. C++ ist deswegen so absurd, weil es abwärtskompatibel zu C > sein mußte. Das war damals korrekt, weil es sich sonst gar nicht hätte > etablieren können, aber der Preis war hoch. Ja da hast du allerdings recht, wenn diese ganze C Scheiße nicht noch in C++ drin wäre... Vor allem sieht man immer wieder Leute, die ein Mix aus C und C++ Erzeugen, C Style casts, raw pointer würg.
PeterPan schrieb: > Also mich reizen ja eher so Features wie Typsicherheit, Referenzen, > Templates (generische Datenstrukturen in C sind ein Krampf), > constexpr... Genau! Um die SW-Entwicklung effizient und sicher zu machen, braucht man ein reiches, domänenspezifisches Typsystem - und genau das ist eine der Stärken von C++. Plakativ könnte man sagen: entweder compiliert das Stück SW und dann ist es auch korrekt, oder es kompiliert erst gar nicht. Weniger plakativ: man spart sich eine Menge Debugging. OOP im engeren Sinn ist eine mögliche Variante, wie ich in C++ programmieren kann, aber nicht die einzige. OOP im engeren Sinn möchte ich auf µC vielleicht auch gar nicht. Da sind doch eher andere Sachen im Spiel wie eben ein reiches Typsystem und Generizität. > Ja da hast du allerdings recht, wenn diese ganze C Scheiße nicht noch in > C++ drin wäre... Vor allem sieht man immer wieder Leute, die ein Mix aus > C und C++ Erzeugen, C Style casts, raw pointer würg. Ja, leider! Das liegt aber eben auch wieder daran, dass nicht jeder wirklich willens ist oder die Zeit bekommt/hat, neue Paradigmen zu erlernen.
:
Bearbeitet durch User
H.J.Gebhardt schrieb: > Allein die Vorgabe des TO, MCs mit viel Flash und RAM zu betrachten, > mildert die Notwendigkeit sparsamer Codierung hier etwas. Was ist den 'viel'? Ich benutze C++ für einen Cortex-M0 mit 16 oder 32 kB Flash und 8 kB RAM und das läuft wunderbar. Der ist schon wesentlich komplexer als ein 8051, aber gerade deshalb möchte ich komplexe Peripherie einfach z.B. mit 'spi.frequency = 1e6;' einstellen und nicht eine Latte von Registern setzen die auch noch bei jedem µC anders ist. Das Zerlegen eines Problemes in Objekte und Interaktionen zwischen diesen ist allerdings schon ein Schritt den man lernen und verstehen muss. Wir (2 Vorreiter) haben auch mal versucht einer Gruppe von knapp ein Dutzend C-Programmiern da C++ zu lehren, das ist auch kläglich gescheitert bzw. schnell eingeschlafen.
Wilhelm M. schrieb: > PeterPan schrieb: > >> Also mich reizen ja eher so Features wie Typsicherheit, Referenzen, >> Templates (generische Datenstrukturen in C sind ein Krampf), >> constexpr... . > Genau! > Um die SW-Entwicklung effizient und sicher zu machen, braucht man ein > reiches, domänenspezifisches Typsystem - und genau das ist eine der > Stärken von C++. Plakativ könnte man sagen: entweder compiliert das > Stück SW und dann ist es auch korrekt, oder es kompiliert erst gar > nicht. Weniger plakativ: man spart sich eine Menge Debugging. . > OOP im engeren Sinn ist eine mögliche Variante, wie ich in C++ > programmieren kann, aber nicht die einzige. OOP im engeren Sinn möchte > ich auf µC vielleicht auch gar nicht. Da sind doch eher andere Sachen im > Spiel wie eben ein reiches Typsystem und Generizität. > >> Ja da hast du allerdings recht, wenn diese ganze C Scheiße nicht noch in >> C++ drin wäre... Vor allem sieht man immer wieder Leute, die ein Mix aus >> C und C++ Erzeugen, C Style casts, raw pointer würg. > > Ja, leider! Das liegt aber eben auch wieder daran, dass nicht jeder > wirklich willens ist oder die Zeit bekommt/hat, neue Paradigmen zu > erlernen. Peter/Wilhelm das will doch keiner hier hören. Wie schon Dan Saks sagte: "If you argue, you loose". Ich nutze lieber die Vorteile, die die meisten hier nicht verstehen (wollen). Und genieße es von ihren Problemen mit den Programmiersprachen für Männer zu lesen.
Carl D. schrieb: > Peter/Wilhelm das will doch keiner hier hören. Wie schon Dan Saks sagte: > "If you argue, you loose". > Ich nutze lieber die Vorteile, die die meisten hier nicht verstehen > (wollen). Und genieße es von ihren Problemen mit den Programmiersprachen > für Männer zu lesen. Ja, das weiß ich ... und gebe es trotzdem nicht auf ;-) (Und warte auf die Einlassungen von c-hater ...)
Johannes S. schrieb: > Peripherie einfach z.B. mit 'spi.frequency = 1e6;' einstellen und nicht Und wenn dann da noch
1 | spi.frequency = 1e6_HZ; |
steht, dann ist das sogar dokumentiert. Stichwort "User Definded Literals".
Wilhelm M. schrieb: > Carl D. schrieb: > >> Peter/Wilhelm das will doch keiner hier hören. Wie schon Dan Saks sagte: >> "If you argue, you loose". >> Ich nutze lieber die Vorteile, die die meisten hier nicht verstehen >> (wollen). Und genieße es von ihren Problemen mit den Programmiersprachen >> für Männer zu lesen. > > Ja, das weiß ich ... und gebe es trotzdem nicht auf ;-) > (Und warte auf die Einlassungen von c-hater ...) C++ nicht zu hassen, ist ein Vorteil, den man nicht aus der Hand geben sollte.
Vincent H. schrieb: > Sheeva P. schrieb: >> Eigentlich ist C++ "in", > > Leider nein. Laut Dan Saks sinkt die Trendlinie von embedded C++ > software, während die von C steigt. > > Siehe hier: > https://www.youtube.com/watch?v=D7Sd8A6_fYU Danke für den Link, den ich allerdings schon kannte. Dans Artikel [1] zum Thema zeichnet IMHO ein wesentlich differenzierteres Bild; vor allem die Tatsache, daß zwischen 2004 und 2005 das Wording der Befragung nur recht geringfügig geändert wurde, und diese geringfügigen Änderungen offenbar gravierende Auswirkungen auf die Ergebnisse gehabt hat, läßt mich an der Aussagekraft dieser Umfragen zweifeln. Auch sonst halte ich solche Umfragen einzelner Seiten für nicht besonders zuverlässig. Webseiten haben üblicherweise ein bestimmtes Publikum, und davon antwortet dann wiederum nur jener Teil auf solche Umfragen, die sich davon angesprochen fühlen. Daß dieser Einfluß vorhanden ist, zeigen die großen Sprünge zwischen 2004 und 2005. Und noch ein anderes Beispiel weist in diese Richtung: den der Verbreitung von Android geschuldeten Erfolg von Java bilden die Ergebnisse der Umfrage überhaupt nicht ab, was vermutlich daran liegt, daß die Seite nur wenige Android-Java-Entwickler anzieht. Von den in solchen Umfragen immer wieder anzutreffenden Manipulationen, gerade im Umfeld von kontroversen Themen wie Programmiersprachen, will ich dabei gar nicht erst anfangen... ;-) Aber dann ist da noch die Frage, wie einzelne Entwickler die Fragen der Umfrage im Zusammenhang mit ihrem Code verstehen. Nehmen wir einen Code, der nur wenige kleine Features von C++ wie Referenzen und / oder Scoped Enums benutzt und ansonsten wie C-Code organisiert und aufgebaut ist: ist das dann noch ein C-Code oder bereits ein C++-Code? Ich persönlich neige zwar zur zweiten, halte aber beide Antworten für völlig legitim -- zumal diese Umfrage ja nach der "primären" Sprache fragt. Hinzu kommt, daß C++ seine Stärken erst mit zunehmender Projektgröße voll entfalten kann. Embedded-Projekte sind ihrer Natur nach aber häufig eher kleine Projkte, bei denen viele besonders positive Eigenschaften von C++ kaum zum Tragen kommen -- und das ist dann auch der Grund dafür, daß sich C++ in diesem Umfeld nicht so schnell durchzusetzen vermag, wie es das ja schon in der Anwendungsentwicklung getan hat. Andererseits weisen diverse Entwicklungen wie "Embedded-C++" und Coding-Standards wie Misra-C++ ja eindeutig darauf hin, daß es ein Interesse und einen Bedarf für C++ auf Embedded-Geräten gibt. Die steigende Verbreitung von ARM-Prozessoren mit ihrer höheren Komplexität, die sich mit C++ besser beherrschen läßt, wird sicherlich ihr Übriges zur Verbreitung von C++ im Embedded-Umfeld dazu tun. Insofern bin ich ausgesprochen zuversichtlich, daß sich C++ auch im Embedded-Umfeld durchsetzen wird. Es dauert nur etwas länger -- na und? ;-) [1] http://www.embedded.com/electronics-blogs/programming-pointers/4372180/Unexpected-trends
Carl D. schrieb: > Johannes S. schrieb: >> Peripherie einfach z.B. mit 'spi.frequency = 1e6;' einstellen und nicht > > Und wenn dann da noch >
1 | spi.frequency = 1e6_HZ; |
> steht, dann ist das sogar dokumentiert. > Stichwort "User Definded Literals". Und mit eine paar templates dazu, kann man sich ein ganze SI-Einheiten System bauen ... dann kann man auch:
1 | auto d1 = 10_km |
2 | auto d2 = 1_mm |
3 | auto d = d1 + d2; |
4 | |
5 | auto s = 1_m; |
6 | auto t = 1_sec; |
7 | |
8 | Velocity = s/t; |
schreiben, und keine Sonde fliegt mehr am Mars vorbei ;-)
Wilhelm M. schrieb: > und keine Sonde fliegt mehr am Mars vorbei ;-) Dafür schlägt sie wegen einer unhandled exception hart auf der Oberfläche auf. :-)) <SCNR>
Jörg W. schrieb: > Wilhelm M. schrieb: >> und keine Sonde fliegt mehr am Mars vorbei ;-) > > Dafür schlägt sie wegen einer unhandled exception hart auf der > Oberfläche auf. :-)) LOL
Wilhelm M. schrieb: >
1 | > auto d1 = 10_km |
2 | > auto d2 = 1_mm |
3 | > auto d = d1 + d2; |
4 | >
|
5 | > auto s = 1_m; |
6 | > auto t = 1_sec; |
7 | >
|
8 | > Velocity = s/t; |
9 | >
|
> > schreiben, und keine Sonde fliegt mehr am Mars vorbei ;-) oder gar >
1 | > auto d1 = 10_km; |
2 | > auto d2 = 1_miles; |
3 | > auto d = d1 + d2; |
4 | >
|
falls auch zukünftig noch Forschung zwischen Metric- und Imperial-Ländern stattfindet. (BTW, das Semikolon ist immer noch Pflicht. C++ != JavaScript)
Jörg W. schrieb: > Wilhelm M. schrieb: >> und keine Sonde fliegt mehr am Mars vorbei ;-) > > Dafür schlägt sie wegen einer unhandled exception hart auf der > Oberfläche auf. :-)) > > <SCNR> Das geht aber besser in Ada. Da kommt die Sonde gar nicht aus der Erdanziehung raus.
H.J.Gebhardt schrieb: > Sheeva P. schrieb: >> C++ einfach mal lernt > > Ein Widerspruch in sich. > Der Umfang gängiger Lehrbücher spricht Bände. Was für ein lahmes Pseudoargument. Es gibt auch sehr schlanke Lehrbücher für C++, zum Beispiel diese: [1,2,3]. Alle unter 500 Seiten; wenn man bedenkt, daß das Standardwerk für C [4], das ja bekanntlich ein Subset von C++ ist, 274 Seiten hat, wird klar, wie niedrig die Schwelle tatsächlich ist -- und insbesondere für erfahrene C-Entwickler, die die C-bezogenen Teile eines C++-Lehrbuches bereits kennen. Und daß man auch über C sehr umfangreiche Bücher schreiben kann, zeigt [5] mit 1190 Seiten. Allerdings halte ich es gerade in diesem Bereich für vollkommen unsinnig, vom Umfang eines Lehrbuches auf die Komplexität einer Sprache zu schließen. Mit mehr Beispielcode läßt sich der Seitenumfang so eines Buches wunderbar aufblähen, während die Autoren nach Seitenzahl bezahlt werden... ;-) [1] https://www.amazon.de/C-Objektorientiertes-Programmieren-von-Anfang/dp/3499600773 [2] https://www.amazon.de/C-eine-Einf%C3%BChrung-Ulrich-Breymann/dp/3446446370 [3] https://www.amazon.de/f%C3%BCr-Dummies-Stephen-R-Davis/dp/3527710981 [4] https://www.amazon.de/Programming-Language-Prentice-Hall-Software/dp/0131103628 [5] https://www.amazon.de/von-bis-umfassende-Handbuch-Computing/dp/3836214113
Nop schrieb: > Das ist formal C++, ja, aber ich finde es albern, ein C-Programm mit > "bool" als C++ zu werten. Das kann man machen, wenn man Statistiken > frisieren will. Weil es scheinbar noch niemanden aufgefallen ist: bool ist ein relativ schlechtes Beispiel, weil es in C seit fast 20 Jahren einen bool gibt (stdbool.h)! Das man den in fast keiner professionellen Library findet (genau so wenig wie `const` oder Variablen mit eingeschränktem Scope) zeigt das Dilema sehr schön auf: Im Embedded Bereich, ist die Software nach wie vor zweitrangig und wird häufig von Laien geschrieben. Dagegen ist auch nichts zu sagen, solange der Umfang und die Komplexität das erlaubt. Vielleicht müssen wir uns einfach daran gewöhnen, dass sich auch der Embedded-Bereich viel weiter auffächert. In Bereichen mit relativ geringen SW-Anteil wird die Software vom E-Techniker mitgemacht. Dieser legt dann Wert darauf, dass die zu verwendende Werkzeuge leicht zu erlernen sind (das wäre dann z.B. C und vor allem eine GUI). In Bereichen, wo die Software einen sehr hohen Anteil an der Entwicklung ausmacht, wird arbeitsteilig gearbeitet. Der E-Techniker macht die Hardware und SW-Techniker macht die Software. Das klingt doch versöhnlich, oder? ;-) mfg Torsten
Torsten R. schrieb: > Das man den in fast keiner professionellen Library findet (genau so > wenig wie `const` oder Variablen mit eingeschränktem Scope) Also const nehme ich andauernd bei der Übergabe von Pointern an eine Funktion, wenn die Funktion nur lesend zugreifen soll. Das ist Teil von selbstdokumentierendem Code, weil man dann schon am Prototypen sieht, daß die Funktion den Datenbereich nicht ändert, ohne daß man sich erst durch den Code wühlen müßte. Und eingeschränkten Scope nutze ich auch gerne. Globals wenigstens file-static (wenn nicht gleich function-static) machen erhöht die Übersicht. Ebenso bei Funktionen, die mache ich auch static, wann immer es geht. Dann weiß man sofort, daß eine Interface-Änderung nur in derselben Datei zu Konsequenzen führen kann. Lokale Variablen, das ist Geschmackssache; wenn die Funktion so lang wird, daß man 1000 Zeilen später nochmal irgendwas mit einer Variablen macht, dann ist nicht der Scope das Problem, sondern die Funktion ist zu lang. Solche Probleme sieht man aber schnell mit Tools wie Sourcemonitor. > Dagegen ist auch > nichts zu sagen, solange der Umfang und die Komplexität das erlaubt. Die Komplexität liegt ja auch weniger in den einzelnen Knoten als vielmehr in deren Zusammenspiel. Witzigerweise ist das eigentlich OOP, weil die einzelnen Controller SELBER die "Objekte" darstellen. Die Methoden sind dann die Firmware, die Getter/Setter sind die Nachrichten auf den IO-Schnittstellen. :-)
Sheeva P. schrieb: > H.J.Gebhardt schrieb: >> Sheeva P. schrieb: >>> C++ einfach mal lernt >> >> Ein Widerspruch in sich. >> Der Umfang gängiger Lehrbücher spricht Bände. > > Was für ein lahmes Pseudoargument. Es gibt auch sehr schlanke Lehrbücher > für C++, zum Beispiel diese: [1,2,3]. Der Umfang irgendwelcher Bücher liefert kaum eine Aussage über die Komplexität einer Programmiersprache, da sie oft unvollständig, ausschweifend oder beides sind. Ein besseres Maß ist IMHO der Umfang der jeweiligen Normen oder – wo es keine gibt – die Referenzdokumente der Sprachentwickler), und zwar nur der reinen Sprachbeschreibung ohne die Bibliotheken. Ich habe hier einmal ein paar Zahlen zusammengestellt:
1 | Sprache Umfang/S Art des Dokuments |
2 | ——————————————————————————————————————————————— |
3 | C11 180 ISO-Norm |
4 | C++14 411 ISO-Norm |
5 | C# 2.0 443 ECMA-Norm |
6 | C# 5.0 468 Sprachreferenz |
7 | C# 7.1 ? kein geschlossenes Dokument |
8 | Java 8 699 Sprachreferenz |
9 | Haskell 153 Sprachreferenz |
10 | ——————————————————————————————————————————————— |
Gemessen an der Mächtigkeit von C++ im Vergleich zu C empfinde ich den Textumfang durchaus noch als akzeptabel. Immerhin scheinen C# und erst recht Java noch fetter zu sein. Dass eine überaus mächtige Sprache nicht komplex sein muss, zeigt Haskell, dessen Dokumentationsumfang sogar C unterbietet. Es gibt allerdings etliche bereits implementierte und häufig genutzte Spracherweiterungen, die voraussichtlich im nächsten Referenzdokument offiziell gemacht werden, so dass dieses evtl. die 200-Seitenmarke überschreiten wird.
Torsten R. schrieb: > weil es in C seit fast 20 Jahren einen bool gibt > (stdbool.h)! Wenn das bool in einer Header-Datei definiert wird / werden muss, dann ist es kein Teil der Sprache sondern eine Erweiterung. Die Dateitypen char, int usw, die sind in der Sprache definiert. > Im Embedded Bereich, ist die Software nach wie > vor zweitrangig und wird häufig von Laien geschrieben. Wie bitte? Es gibt einen Riesenindustrie für Embedded Software und ich würde nicht behaupten wollen das seien alles Laien die da Software schreiben!
Torsten R. schrieb: > Im Embedded Bereich, ist die Software nach wie vor zweitrangig und wird > häufig von Laien geschrieben. Das ist doch Unfug: wenn die Leute dafür bezahlt werden, sind sie per definitionem erstmal Profis und keine Amateure. Dass es keine Informatiker sind, ist wiederum normal: Informatiker sind von der Ausbildung her nicht unbedingt sehr anwendungsnah, dafür können sie prima Algorithmen und Frameworks bauen. Das heißt natürlich nicht, dass nicht auch Informatiker sich in die „niederen Ebenen“ einarbeiten könnten, aber genauso gut darfst du den nicht-SW-Ings zugestehen, dass sie ausreichend Handwerkszeug für die Programmierung erlernen können, um darin firm zu sein. Mit Programmiersprachen hat das alles nicht viel zu tun, dafür in der Wirtschaft oft umsomehr mit äußeren Randbedingungen: irgendwer muss das Geld ja bezahlen. Nicht jedes Projekt entsteht immer von Grund auf neu, und wenn es erstmal besteht, ist man eben in der Wahl der Programmiersprache nicht mehr so frei, wie man sich das wünschen würde. Da kann man noch so gut die Vorzüge von C++ gegenüber C kennen, es wird einem kein $KUNDE freiwillig die Zeit bezahlen, das völlig neu aufzusetzen, solange das existierende die gewünschten Ergebnisse bringt und weniger Aufwand für ihn kostet.
:
Bearbeitet durch Moderator
Eric B. schrieb: > Wenn das bool in einer Header-Datei definiert wird / werden muss, dann > ist es kein Teil der Sprache sondern eine Erweiterung. Die Dateitypen > char, int usw, die sind in der Sprache definiert. _Bool ist seit knapp 20 Jahren genauso in der Sprache definiert. Nur bool konnte man nicht nachträglich reindefinieren, da es eine Inkompatibilität bestehender Programme bedeutet hätte, denn dieser Name war zuvor im application name space. Daher entsteht die Äquivalenz von _Bool nach bool nur dann, wenn man <stdbool.h> inkludiert.
Jörg W. schrieb: > Eric B. schrieb: > >> Wenn das bool in einer Header-Datei definiert wird / werden muss, dann >> ist es kein Teil der Sprache sondern eine Erweiterung. Die Dateitypen >> char, int usw, die sind in der Sprache definiert. > > _Bool ist seit knapp 20 Jahren genauso in der Sprache definiert. Ups, zu spät mit der Antwort: http://en.cppreference.com/w/c/types/boolean
Eric B. schrieb: > Torsten R. schrieb: >> weil es in C seit fast 20 Jahren einen bool gibt >> (stdbool.h)! > > Wenn das bool in einer Header-Datei definiert wird / werden muss, dann > ist es kein Teil der Sprache sondern eine Erweiterung. Die Dateitypen > char, int usw, die sind in der Sprache definiert. Ja, genau so etwas meine ich: Da schreiben Leute Software, denen nicht einmal klar ist, dass zu einer Sprache eben nicht nur eine Menge reservierter Wörter gehört, sondern in erheblichen Umfang auch Bibliotheken (der C buldin Type lautet übrigens _Bool). Die sind Teil der Sprache und werden auch ganz genau in der Definition der Sprache beschrieben. Da schreibt sich jeder seine eigenen header mit typedefs für u8, u16 usw. statt sich einmal einen Nachmittag hin zu setzen und zu gucken, was die Sprache den schon so an Typen definiert und damit, mit jedem Compiler frei Haus geliefert wird.
Jörg W. schrieb: > Torsten R. schrieb: >> Im Embedded Bereich, ist die Software nach wie vor zweitrangig und wird >> häufig von Laien geschrieben. > > Das ist doch Unfug: wenn die Leute dafür bezahlt werden, sind sie > per definitionem erstmal Profis und keine Amateure. Damit hast Du natürlich recht. Ich relativiere das mal: Im Embedded Bereich, gibt es Projekte in denen bietet die Software nach wie vor nicht den Hauptnutzen eines Produkts und wird von Kollegen geschrieben, deren Hauptfokus wo anders liegt.
Ich verwende am liebsten C++, auf kleineren µC oder wenn die Entwicklungsumgebung/runtime-lib besser ist auch C und inline-ASM. Bisher hat das immer gereicht. Reinen Assembler könnte ich auch verwenden, aber das ist für mich in 100% der Praxisfälle unnötig und wäre eher etwas sportliches.
Ach ja, zum Thema "C nur für kleine Projekte geeignet": Wenn man den Linuxkernel mit weit über 20 Mio Codezeilen als "klein" betrachtet, dann ja. Es ist auch nicht so, wie gerne dargestellt, daß Torvalds kein C++ mag, daß er zu blöd dazu gewesen wäre und was sonst noch gerne behauptet wird. Vielmehr ist das Interessante, daß genau die Vorteile von C++ auch als Nachteile gesehen werden können. Geht ja schon bei Operator-Überladung los, wo jedes Pluszeichen einen riesigen Rattenschwanz bedeuten kann, aber das sieht man beim lokalen Review halt nicht auf den ersten Blick. Die ganze Compilermagic ist nicht nur ein Argument für C++, sondern auch eines dagegen. "Muß man nicht nutzen?" Ja, in Kleinprojekten, wenn man der Einzige ist. Bei Großprojekten ist der garantierte Weg, wie etwas tatsächlich nicht genutzt wird, daß die Sprache es nicht kann. Und wenn Dann Saks mit "wer argumentiert, verliert" ankommt: diese Haltung kenne ich ansonsten von religiösen Missionaren, die nicht nachvollziehen können, wieso ihre Argumente nicht ankommen. Wenn sowas dann auch noch von jemandem kommt, der selber kein einziges embedded Industrieprojekt realisiert hat, wird es vollends lächerlich.
Nop schrieb: > Ach ja, zum Thema "C nur für kleine Projekte geeignet": Wenn man den > Linuxkernel mit weit über 20 Mio Codezeilen als "klein" betrachtet, dann > ja. Wobei der Linux-Kernel zum allerallergrößten Teil aus Treibern besteht und insofern trotz > 20 Millionen LOC kein typisches "großes Projekt" ist. > Es ist auch nicht so, wie gerne dargestellt, daß Torvalds kein C++ mag, Doch, genau so ist es. > daß er zu blöd dazu gewesen wäre Es ist ihm zu einfach, die STL und die Boost-Libraries sind ihm nicht stabil genug (als wäre das ein Argument gegen die Sprache, und nicht eines gegen die Stabilität der besagten Bibliotheken und Implementierungen), ... er mag C++ einfach nicht und sucht sich daher "Argumente" dagegen, damit er seinen Aussagen wenigstens den Anschein einer sachlichen Begründung geben kann. Obendrein ist es ja nicht so, als ob Linus Torvalds der einzig wahre Programmiergott und seine Ansichten die einig wahre Wahrheit seien; viele andere bekannte und nicht minder fähige und talentierte Entwickler sehen das vollkommen anders als Linus. Insofern ist es nichts weiter als eine ganz besonders lächerliche Variante des "argumentum ad populum", sich in diesem Punkt ausschließlich auf Linus' Aussagen zu berufen. > Vielmehr ist das Interessante, daß genau die Vorteile von C++ auch > als Nachteile gesehen werden können. > > Geht ja schon bei Operator- Überladung los, wo jedes Pluszeichen einen > riesigen Rattenschwanz bedeuten kann Nein, eigentlich nicht. Bessere Codeorganisation und Wiederverwendbarkeit sind schwer meßbar, aber dennoch harte Kriterien und eindeutige Vorteile. Richtig ist allerdings auch, daß C++ -- vor allem wegen der geforderten Abwärtskompatibilität mit C -- einige Altlasten mit sich herumschleppt. Die Überladung von Operatoren und Operationen ist ein sehr sinnvolles und mächtiges Feature, und wie jedes mächtige Feature kann sie auch mißbraucht werden. Aber das ist dann kein Argument gegen das Feature, sondern erstens eines gegen den, der sie mißbraucht, und zweitens gegen seinen Code. Denn schlechten, unlesbaden und unverständlichen Code kann man in jeder Sprache schreiben -- die Perlianer haben mit dem "Obfuscated Perl Contest" sogar einen Kunstwettbewerb daraus geschaffen. > Und wenn Dann Saks mit "wer argumentiert, verliert" ankommt: diese > Haltung kenne ich ansonsten von religiösen Missionaren, die nicht > nachvollziehen können, wieso ihre Argumente nicht ankommen. Naja, "jeden Vorteil kann man auch als Nachteil sehen" ist jedenfalls auch nicht allzu weit davon entfernt. ;-) Außerdem sagt Dan nicht: "wer argumentiert, verliert", sondern: "wenn Du streitest, verlierst Du". Es ist beliebt, aber trotzdem ein Mißverständnis, das englische "to argue" mit dem deutschen "argumentieren" gleichzusetzen; korrekterweise wäre die Übersetzung von "to argue" eher "streiten". Zudem ignorierst Du den Satz, den Dan davor sagt: "when it comes to persuasion", mithin: "wenn wir über Überzeugung reden", "wenn es um Überzeugung geht" oder "wenn es darum geht, jemanden zu überzeugen". Zusammen heißt das, was Dan sagt, also grob übersetzt: "wenn Du jemanden überzeugen willst und mit ihm streitest, dann verlierst Du". Und wenn Du diese Aussage als religiöse Missionierung verstehst, solltest Du Dir nochmal das kleine Einmaleins der Kommunikation zu Gemüte führen. ;-) > Wenn sowas dann auch noch von jemandem kommt, der selber kein einziges > embedded Industrieprojekt realisiert hat, wird es vollends lächerlich. Er hat kein einziges Industrieprojekt mit C++ realisiert -- verstehst Du den Unterschied zu Deiner Aussage?
Wer das große Instrumentarium von C++ bzw. objektorientierte Herangehensweisen ohnehin schon (richtig, d.h. ohne Systemressourcen zu verschleudern) beherrscht kann sie ja durchaus auch durchgängig für MC verwenden. Da spricht doch gar nichts dagegen. Aber: Daß sich Zeit und Mühe aber lohnen es sich extra dafür aneignen zu wollen würde ich entschieden bestreiten. Einfache Controller sind mit einfachen Sprachen besser bedient. Sheeva P. schrieb: > und wie jedes mächtige Feature kann sie auch > mißbraucht werden. Aber das ist dann kein Argument gegen das Feature, > sondern erstens eines gegen den, der sie mißbraucht, und zweitens gegen > seinen Code. Ganz klar, bei soviel technokratischer Sichtweise ist natürlich immer der programmierende Mensch "schuld", nie die Programmiersprache. Daß Werkzeuge als solche auch ihre Qualitäten haben, daß sie je nach Anwendungsfall sinnvoller oder weniger sinnvoll, passend oder überdimensioniert sein können kommt Dir wohl nicht in den Sinn? Sheeva P. schrieb: > Codeorganisation und > Wiederverwendbarkeit bieten mehr oder weniger alle Programmiersprachen. Wenn hier "höheres" C++ definitiv noch ausgefeiltere Möglichkeiten bietet dann ist das höchstens für große Projekte, große MC und Prozessoren überhaupt von Belang.
> Wer das große Instrumentarium von C++ bzw. objektorientierte > Herangehensweisen ohnehin schon ... beherrscht kann sie ja > durchaus auch durchgängig für MC verwenden. > Da spricht doch gar nichts dagegen. Dagegen spricht, dass µC in der Regel keine so ausgefuchste Speicherverwaltung haben, wie die ausgewachsenen Server Betriebssysteme. In Kombination mit knapp bemessenem RAM kommst man schnell zu einem Out-Of-Memory wegen Heap-Fragmentierung. Also "durchgängig" ist hier nicht passend. Man kann C++ auf Mikrocontrollern verwenden, aber nur eingeschränkt.
Stefan U. schrieb: >> Wer das große Instrumentarium von C++ bzw. objektorientierte >> Herangehensweisen ohnehin schon ... beherrscht kann sie ja >> durchaus auch durchgängig für MC verwenden. >> Da spricht doch gar nichts dagegen. > > Dagegen spricht, dass µC in der Regel keine so ausgefuchste > Speicherverwaltung haben, wie die ausgewachsenen Server Betriebssysteme. > In Kombination mit knapp bemessenem RAM kommst man schnell zu einem > Out-Of-Memory wegen Heap-Fragmentierung. > > Also "durchgängig" ist hier nicht passend. Man kann C++ auf > Mikrocontrollern verwenden, aber nur eingeschränkt. Ob man C++ nutzt oder nicht hat aber nur eingeschränkt etwas mit Heap-Verwaltung zu tun: Objektorientierung im engeren Sinn (v.a. Laufzeitpolymorphie) ist sicher auf µC mit wenig RAM unangebracht. Aber das ist ja nur ein kleiner Teil: C++ ist eine multi-paradigmen Sprache. Ich kann objektorientiert (im weiteren Sinn) programmieren ohne dyn. Speicherverwaltung, ich kann generisch programmieren, funktional (zu einem gewissen Teil), ein reiches Typsystem verwenden, ...
Sheeva P. schrieb: > Wobei der Linux-Kernel zum allerallergrößten Teil aus Treibern besteht > und insofern trotz > 20 Millionen LOC kein typisches "großes Projekt" > ist. Sehe ich nicht als relevantes Argument. > Doch, genau so ist es. Ja gut, insofern habe ich mich da lax ausgedrückt: es ist nicht so, daß er es aus Geschmacksgründen oder emotionalen Befindlichkeiten heraus nicht mag, sondern er lehnt es aus guten Gründen ab. > Insofern ist es nichts weiter als eine ganz besonders > lächerliche Variante des "argumentum ad populum" Ach? Wieso kam diese Kritik nicht bereits bei den Videos von Dan Saks? Der übrigens seiner eigenen Aussage nach kein einziges embedded Industrieprojekt gemacht hat? Während Torvalds mit dem Linuxkernel und auch mit Git immerhin relevante Projekte vorzeigen kann? > Nein, eigentlich nicht. Doch, weil man Reviews dann nicht mehr lokal machen kann, denn C++ ist sehr kontextabhängig. Jedes popelige Pluszeichen kann diverse Additionen in Schleifen bedeuten. Jeder elementare Operator ist möglicherweise ein Funktionsaufruf, aber man sieht an der Stelle nicht, welche Funktion aufgerufen wird. Dazu muß man sich dann erstmal durch weitere Dateien wühlen. Es geht dabei nichtmal darum, den Plus-Operator etwa zum Zwecke einer Division mißbräuchlich zu überladen (das tut real niemand), sondern daß es bei bestimmungsgemäßem Gebrauch schon problematisch wird. > Denn schlechten, unlesbaden und unverständlichen Code kann > man in jeder Sprache schreiben -- die Perlianer haben mit dem > "Obfuscated Perl Contest" sogar einen Kunstwettbewerb daraus geschaffen. Den gibt's auch für C. Für C++ nicht, weil obfuscated Code in C++ zu schreiben keine Kunst darstellt, man braucht bloß normalen Produktivcode zu nehmen. ;-) > Naja, "jeden Vorteil kann man auch als Nachteil sehen" ist jedenfalls > auch nicht allzu weit davon entfernt. ;-) Finde ich nicht. Es ist halt eine völlig andere Sichtweise. Sie erklärt auch, wieso das Anpreisen von noch mehr Features nicht überzeugt, im Gegenteil. > "wenn Du jemanden überzeugen willst und mit ihm streitest, dann > verlierst Du". Thx, guter Absatz. > Er hat kein einziges Industrieprojekt mit C++ realisiert -- verstehst Du > den Unterschied zu Deiner Aussage? Äh, ja, sorry, das meinte ich auch. Natürlich hat er Industrieprojekte realisiert, allerdings in Assembler und C.
Stefan U. schrieb: > Dagegen spricht, dass µC in der Regel keine so ausgefuchste > Speicherverwaltung haben, wie die ausgewachsenen Server Betriebssysteme. > In Kombination mit knapp bemessenem RAM kommst man schnell zu einem > Out-Of-Memory wegen Heap-Fragmentierung. Man muß Objekte ja nicht mit new anlegen, man kann sie auch statisch anlegen. Analog dazu muß man in C ja auch keine Speicherbereiche via malloc holen, man kann sie auch als Arrays anlegen. Dynamische Speicherallozierung von Dingen, die viel Speicher brauchen, aber nie zugleich anfallen, löse ich in C über den Stack. Dann fragmentiert das nie.
Nop schrieb: > Doch, weil man Reviews dann nicht mehr lokal machen kann, denn C++ ist > sehr kontextabhängig. Jedes popelige Pluszeichen kann diverse Additionen > in Schleifen bedeuten. Jeder elementare Operator ist möglicherweise ein > Funktionsaufruf, aber man sieht an der Stelle nicht, welche Funktion > aufgerufen wird. Dazu muß man sich dann erstmal durch weitere Dateien > wühlen. Das ist schlicht Unsinn! Was ist der Unterschied bei einem Review von
1 | list += item; |
zu
1 | list_add(list, item); |
? In beiden(!) Fällen muss ich mir ggf. die Operation ansehen, egal wie sie syntaktisch geschrieben wurde.
Wilhelm M. schrieb: > Was ist der Unterschied bei einem Review von > list += item; > zu > list_add(list, item); > ? Beim zweiten Fall bin ich mir 100%ig sicher, dass ich mir die Operation anschauen muss. Im ersten Fall könnte man bei flüchtigem Blick und in der Annahme, dass es sich um eine simple Addition handelt - darüber hinwegsehen.
Frank M. schrieb: > Wilhelm M. schrieb: >> Was ist der Unterschied bei einem Review von >> list += item; >> zu >> list_add(list, item); >> ? > > Beim zweiten Fall bin ich mir 100%ig sicher, dass ich mir die Operation > anschauen muss. Im ersten Fall könnte man bei flüchtigem Blick und in > der Annahme, dass es sich um eine simple Addition handelt - darüber > hinwegsehen. Man könnte ... klar. Aber dann hat man keine Ahnung von C++. Und das gilt für jede Sprache: jede hat ihre Eigenheiten, die man kennen muss. Man könnte auch grundsätzlich "übersehen", dass bestimmte Algorithmen aufwändiger sind als andere ...
Wilhelm M. schrieb: > In beiden(!) Fällen muss ich mir ggf. die Operation ansehen, egal wie > sie syntaktisch geschrieben wurde. Nein. In C weißt Du im ersten Fall, daß es eine einfache Addition ist, weil es keine Überladung gibt. Wenn man bedenkt, wie man z.B. im Linuxkernel Patches reviewed, nämlich vorzugsweise differentiell und lokal, weil man sonst zu gar nichts mehr kommt - dann ist klar, wieso ein expliziter Funktionsaufruf wesentlich leserlicher ist. Der heißt nämlich "Achtung, hier könnte eine Performance-Falle lauern". Es geht nicht darum, daß man das bei C++ nicht weiß, sondern daß C++ die ausgeführte Operation vor dem Leser versteckt. Abstraktion wird zu Obfuscation, und es spart keine Zeit, sondern kostet mehr Zeit, sich da durchzuwühlen.
Wilhelm M. schrieb: > Man könnte ... klar. Aber dann hat man keine Ahnung von C++. Und das > gilt für jede Sprache: jede hat ihre Eigenheiten, die man kennen muss. Ja, natürlich. Aber theoretisch müsstest Du Dir bei einem Code-Review jede theoretisch mögliche Überlagerung eines Operators anschauen, selbst wenn es sich um die Addition zweier simpler Integer-Variablen handelt. Das macht es "anstrengender". Und damit erhöht sich die Gefahr, dass man etwas übersieht. Genau das meinte ich mit "darüber hinwegsehen". Bei einem expliziten Funktionsaufruf bin ich als Code-Reviewer gezwungen, mir diese anzuschauen. Da gibt es keinen Zweifel. Aber ich will C++ nicht schlechtreden. Es ist schon ein geniales Werkzeug. Angesichts der vielen Erweiterungen und potentiellen Möglichkeiten, die in den letzten 20 Jahren hinzugekommen sind, kann ich mir aber gut vorstellen, dass ein nicht unerheblicher Teil von Programmierern damit schlichtweg "überfordert" ist. P.S. Ich selbst habe vor 20 Jahren in einem größeren Programmierer-Team für ein großes Telekommunikationsunternehmen (jeder kennt die Farbe) gearbeitet, wo es um die Rechnungsstellung der Netze zwischen den Mobilfunkunternehmen ging. Klare Vorgabe war C++. Aber programmiert wurde tatsächlich alles in C. Bis auf das Schlüsselwort "class" wurde da nichts weiter von den eigentlichen C++-Mitteln genutzt. Der Grund war einfach: Die Leute konnten es nicht besser.
:
Bearbeitet durch Moderator
Wilhelm M. schrieb: > Man könnte ... klar. > Aber dann hat man keine Ahnung von C++. Und das gilt für jede Sprache: > jede hat ihre Eigenheiten, die man kennen muss. > Man könnte auch grundsätzlich "übersehen", dass bestimmte Algorithmen > aufwändiger sind als andere ... Das sehe ich ähnlich. Das Überladen von Operatoren empfand ich schon damals als wirklich hilfreich und einen großen Fortschritt gegenüber C. Es gestaltet den Code deutlich besser lesbar und entspricht viel mehr der menschlichen Intuition. obstkorb = apfel + birne + orange + zitrone finde ich viel klarer als ein Wust aus Funktionsaufrufen. Meiner Meinung nach sinkt dadurch die Fehleranfälligkeit. Dass man aber natürlich vor dem Betrachten von C++-Code davon gehört haben sollte, dass es sowas gibt, sollte selbstverständlich sein. Im übrigen gab es schon damals Editoren, die solche überladenen Operatoren (und nur solche) farblich gekennzeichnet haben, so dass sie einem sofort ins Auge fallen. Ich nehme mal an, dass man heute mit einem Klick darauf direkt zu der Überladung geführt wird. "Hab ich nich' gesehen" lasse ich also nicht gelten ;-)
:
Bearbeitet durch Moderator
Chris D. schrieb: > Es gestaltet den Code deutlich besser lesbar und entspricht viel mehr > der menschlichen Intuition. > > obstkorb = apfel + birne + orange + zitrone > > finde ich viel klarer als ein Wust aus Funktionsaufrufen. > > Meiner Meinung nach sinkt dadurch die Fehleranfälligkeit. Diese Betrachtungsweise legt nahe, das das Überladen der Operatoren nur "syntaktischer Zucker" sei. Dem ist aber nicht so. Ein wesentlicher Aspekt bei C++ ist ja die weitgehende Gleichbehandlung von primitiven DT und UDT. Daher brauche ich die Operatorüberladung bei generischem Code zwingend (das motiviert auch, warum ich freie Funktionen brauche).
Wilhelm M. schrieb: > Diese Betrachtungsweise legt nahe, das das Überladen der Operatoren nur > "syntaktischer Zucker" sei. > Dem ist aber nicht so. Ein wesentlicher Aspekt bei C++ ist ja die > weitgehende Gleichbehandlung von primitiven DT und UDT. Daher brauche > ich die Operatorüberladung bei generischem Code zwingend (das motiviert > auch, warum ich freie Funktionen brauche). Stimmt. Danke für die wichtige Ergänzung - bin wohl doch schon zu lange aus dem C++-Geschäft raus :-/ Aber ich ändere das gerade wieder: Beitrag "Buchempfehlung? Aktuelles C++-Buch für C-Programmierer mit C++-Grundlagen" :-)
Was allerdings in C holprig ist, sind generische Datenstrukturen. Der Library-Quicksort muß für jeden Vergleich einen Funktionsaufruf machen, der nichtmal inline-fähig ist. C-Qsort ist daher ziemlich lahm. Man kann das natürlich abstellen, indem man einfach eine explizite Funktion schreibt, was aber mehr Codegröße bewirkt, wenn es mehr als eine Datenstruktur zu sortieren gibt. In C++ ist das kein Problem. Man braucht keine expliziten Funktionen mehrfach hinschreiben und hat trotzdem nicht diesen indirekten Funktionsaufruf für die Vergleiche. Frage: Angenommen, man will denselben Sortieralgorithmus auf zwei verschiedene Datenstrukturen anwenden in C++, was fällt bei C++ dann am Ende in Maschinencode raus? Sind das auch separate Funktionen, also von der Codegröße her dasselbe wie mit C und separatem Hinschreiben?
Nop schrieb: > Was allerdings in C holprig ist, sind generische Datenstrukturen. Der > Library-Quicksort muß für jeden Vergleich einen Funktionsaufruf machen, > der nichtmal inline-fähig ist. C-Qsort ist daher ziemlich lahm. Man kann > das natürlich abstellen, indem man einfach eine explizite Funktion > schreibt, was aber mehr Codegröße bewirkt, wenn es mehr als eine > Datenstruktur zu sortieren gibt. > > In C++ ist das kein Problem. Man braucht keine expliziten Funktionen > mehrfach hinschreiben und hat trotzdem nicht diesen indirekten > Funktionsaufruf für die Vergleiche. > > Frage: Angenommen, man will denselben Sortieralgorithmus auf zwei > verschiedene Datenstrukturen anwenden in C++, was fällt bei C++ dann am > Ende in Maschinencode raus? Sind das auch separate Funktionen, also von > der Codegröße her dasselbe wie mit C und separatem Hinschreiben? Du wetterst in Deinen obigen Beiträgen so gegen C++, aber hast Dich offenbar noch nicht wirklich damit befasst! Schau mal bei template-Instanziierung nach ;-)
Wilhelm M. schrieb: > Du wetterst in Deinen obigen Beiträgen so gegen C++, aber hast Dich > offenbar noch nicht wirklich damit befasst! Damit, was am Ende in Maschinencode rausfällt, in der Tat nicht, nein. Das wäre mir auch zu mühsam, weil mir dabei genau die ganze zusätzliche Abstraktion in den Weg gelegt wird. Sobald mir das Ergebnis auf Maschinencode-Ebene relevant ist, nehme ich in der Praxis lieber eine Sprache, die mir da weniger Versteckspiel aufzwingt. Aber halt aus Interesse.
Nop schrieb: > Wilhelm M. schrieb: > >> Du wetterst in Deinen obigen Beiträgen so gegen C++, aber hast Dich >> offenbar noch nicht wirklich damit befasst! > > Damit, was am Ende in Maschinencode rausfällt, in der Tat nicht, nein. Das brauchst Du auch nicht: Du musst nur generell wissen, was eine template-Instanziierung ist. So ähnlich wie Du Dich fragen musst, was eine Funktion list_add() wohl macht. Unterschied: das eine passiert zur Laufzeit, das andere zur Compilezeit. Die template-Engine ist übrigens turing-vollständig ... mit Metafunktionen kann man also beliebig rechnen, wobei constexpr-Funktionen das sehr schön vereinfachen.
Wilhelm M. schrieb: > Das brauchst Du auch nicht: Du musst nur generell wissen, was eine > template-Instanziierung ist. Hm ja, komplexere, u.a. auf den Datentyp parametrierbare Macros. Mit der overhead-freien Variante wäre die Codegröße dann dieselbe.
> entschieden bestreiten. Einfache Controller sind mit einfachen Sprachen > besser bedient. Das sehe ich auch so. Ich wuerde sogar fast sagen das dies unbestritten ist. Aber es wird bald keine einfachen Controller mehr geben. Zum Teil schon jetzt, spaetestens aber mit dem naechsten Generationssprung wirst du relativ dicke Controller fuer unter einem Euro bekommen. Und als professioneller Entwickler wirst du zu der Erkenntnis kommen das du einen erheblichen Teil deiner Arbeit mit komplexen Controllern verbringst. Dann koenntest du die dafuer notwendigen Kenntnisse und Faehigkeiten auch fuer die wenigen Projekte mit schlichten Controllern verwenden. Es zahlt sich also schon aus ueber die Zeit nach dem einfachen C nachzudenken. Olaf
Torsten R. schrieb: > Ja, genau so etwas meine ich: Da schreiben Leute Software, denen nicht > einmal klar ist, dass zu einer Sprache eben nicht nur eine Menge > reservierter Wörter gehört, sondern in erheblichen Umfang auch > Bibliotheken Gottseidank schreibe ich schon lange keine Software mehr :-P > (der C buldin Type lautet übrigens _Bool). I stand corrected, danke für die Aufklärung. Meine einzige Ausrede ist, dass ich in einem beruflichen Umfeld arbeite, dass technisch noch etwa 20 Jahre hinterher hüpft. C99 wird damit wohl erst in 2019 erlaubt werden ;-) > Die sind Teil der Sprache und werden auch ganz genau in der Definition > der Sprache beschrieben. Hm, da bin ich andere Meinung. Auch wenn in der Standard eine ganze Latte an Bibiliotheken beschrieben wird, die mitgeliefert werden soll, sind sie nicht Teil der Sprache: ich muss als Programmierer dem Compiler mitteilen, (über #include o.Ä.) dass er bitteschön irgendwelche Typen, Funktionen usw. interpretieren soll. Wenn ich dir sage, dass du überall wo "Blobfutzl" steht "Weissbier" lesen sollst, könen wir über "Blobfutzl" reden. Das macht es aber nicht Teil der deutsche Sprache. > Da schreibt sich jeder seine eigenen header mit typedefs für u8, u16 > usw. statt sich einmal einen Nachmittag hin zu setzen und zu gucken, was > die Sprache den schon so an Typen definiert und damit, mit jedem > Compiler frei Haus geliefert wird. Ohhh, die Diskussion hatte ich schon mal bei der Arbeit. Wir dürften da tatsächlich die Standard-Headers nicht benutzen, da man ja nie wissen konnte wie da drinnen Gott-weiss-was-alles definiert war. Also mussten tatsächlich im Haus geschriebene Headers mit eigenen, zum Teil sogar fehlerhafte typedefs fur u8 und co eingesetzt werden.
olaf schrieb: > Aber es wird bald keine einfachen Controller mehr geben. Doch, wird es, allein schon wegen Stromverbrauch, die nie gering genug sein kann. Außerdem gibt es heute bereits komplexe Controller mit viel mehr Wums, das sind die Cortex-A. Die könnten von Kosten und Stromverbrauch her auf künftig auf die Werte eines heutigen M0 sinken per technischem Fortschritt. Da ist C++ aber auch keine Lösung, die programmiert man gar nicht mehr bare metal. Das geht praktisch einfach nicht. Echtzeit kann man sich dann allerdings auch abschminken. Und genau deswegen wird es auch weiterhin einfache Controller geben, weil es einen Industriebedarf gibt, daß man leicht reviewbaren Code innerhalb der Anforderungen erstellen kann. Immerhin wird sogar der 8051 auch heute noch eingesetzt.
Eric B. schrieb: > Auch wenn in der Standard eine ganze Latte an Bibiliotheken beschrieben > wird, die mitgeliefert werden soll, sind sie nicht Teil der Sprache Zumindest in C sind sie das: du darfst im eigenen Code beispielsweise eben keine eigene printf-Implementierung haben, sondern wenn da "printf" steht, ist das gemäß Standard gemeint, und es ist dem Compiler überlassen, wie er das interpretiert. Ein typisches Beispiel dafür ist, dass GCC aus
1 | printf("foo\n"); |
ein
1 | puts("foo"); |
macht, um den Interpretations-Overhead für den Formatstring zu vermeiden. Damit ist die Standardbibliothek aus Sicht der Sprach-Normierer ein Teil der Sprache. Alles zusammen ist dann “the implementation”.
> Doch, wird es, allein schon wegen Stromverbrauch, die nie gering genug > sein kann. Gerade wegen dem Stromverbrauch setze ich ziemlich komplexe und dicke Controller weil weil sich da alles abschalten laesst und nur gelegentlich eingeschaltet wird und die aktive Zeit moeglich kurz sein kann und man halt sehr viel mehr skalieren kann. Olaf
olaf schrieb: > Gerade wegen dem Stromverbrauch setze ich ziemlich komplexe und dicke > Controller weil weil sich da alles abschalten laesst Nur der Leckstrom nicht … und der steigt mit sinkenden Strukturgrößen.
Frank M. schrieb: > Wilhelm M. schrieb: >> Man könnte ... klar. Aber dann hat man keine Ahnung von C++. Und das >> gilt für jede Sprache: jede hat ihre Eigenheiten, die man kennen muss. > > Ja, natürlich. Aber theoretisch müsstest Du Dir bei einem Code-Review > jede theoretisch mögliche Überlagerung eines Operators anschauen, selbst > wenn es sich um die Addition zweier simpler Integer-Variablen handelt. > Das macht es "anstrengender". Und damit erhöht sich die Gefahr, dass man > etwas übersieht. Genau das meinte ich mit "darüber hinwegsehen". Ne, ganz so schlimm ist es nicht. In C++ kannst Du keine eigene Definition für operator+(int,int) angeben. Mindestens ein Operand muss Benutzer definiert sein. Wenn Dir als Reviewer nicht auffällt, dass einer der beiden Operanden Benutzer definiert ist, dann ist der Code wohl eh schon recht ungünstig Strukturiert. > Bei einem expliziten Funktionsaufruf bin ich als Code-Reviewer > gezwungen, mir diese anzuschauen. Da gibt es keinen Zweifel. So weit würde ich nicht gehen. Wenn jedes Stück Code im Projekt gereviewed wurde, dann auch die aufgerufene Funktion. Der Reviewer prüft dann, ob operator+ der richtige Name für die Funktion ist (do it like the ints do). Operatoren werden in C++ eigentlich "relativ" selten verwendet, weil die Menge der zur Verfügung stehenden "Funktionsnamen" recht überschaubar ist und die Bedeutung jedes Operators recht klar definiert ist.
Ich mag Operator-Überladung gar nicht und nutze es daher auch nur, wenn
ich durch Libraries dazu gezwungen werde. Stattdessen benutze ich lieber
Methoden mit sprechenden Namen (im Java Style), zum Beispiel
MyList::append(element).
Aber ich mag die Sprache dennoch. Es zwingt mich ja niemand dazu, jedes
Feature zu nutzen. Dann benutze ich halt nur das, was mir zusagt. Selbst
für andere Entwickler ist das in der Praxis kein Hindernis, meine Codes
weiter zu verwenden oder gar zu ändern.
Leite, die sich über solche Kleinigkeiten einen zu großen Kopf machen,
nenne ich gerne "Künstler". Sie neigen auch dazu, ihr Programm so zu
behandeln, wie die Glucke über ihre Küken wacht. Am liebsten darf das
niemand verändern. ich habe schon mehrmals zugesehen, dass "Künstler"
wegen diesem Verhalten entlassen wurden.
> Operatoren werden in C++ eigentlich "relativ" selten verwendet
Leider denkt nicht jeder Entwickler so vernünftig. Die meisten aber
schon. Ich habe nur selten Code gesehen, wo Operatoren auf überraschende
Weise überladen wurde. Wovon Stroustrup übrigens zu recht dringend
abrädt.
> Gerade wegen dem Stromverbrauch setze ich ziemlich komplexe und dicke > Controller weil weil sich da alles abschalten laesst Na dann schalte mal bei einem noch relativ schlanken STM32F103 alles abschaltbare ab (außer Wake-Up per externem Signal) und vergleiche die Stromaufnahme mit irgendeinem beliebigen AVR oder PIC. Was in der AVR Welt typischerweise it "Super Low Power Consumption" hochgepriesen wird, ist immer noch mindestens um Faktor 10 über dem, was man von gewöhnlichen 8bit Controllern gewohnt ist. Sicher gibt es tatsächlich (nicht durch Marketing erlogene) sparsame ARM Controller, aber wenn du die mit den speziellen Low-Power 8bit Controllern vergleichst (sagen wir mal, was in Taschenrechnern und Uhren steckt), dann liegen auch da wieder Welten zwischen.
Eric B. schrieb: > Wenn ich dir sage, dass du überall wo "Blobfutzl" steht "Weissbier" > lesen sollst, könen wir über "Blobfutzl" reden. Das macht es aber nicht > Teil der deutsche Sprache. Naja, mit solchen Vergleichen, kannst Du Alles und Nix belegen. Sollten wir Techniker den Politikern und Theologen überlassen ;-)
olaf schrieb: > Gerade wegen dem Stromverbrauch setze ich ziemlich komplexe und dicke > Controller weil weil sich da alles abschalten laesst Cortex-A hat einen wesentlich höheren Stromverbrauch als Cortex-M, und Cortex-M4 mehr als Cortex-M0. Darüberhinaus ist das An/Abschalten von Sachen auch nur eine API-Funktion, innerhalb derer man ein paar Register bedient. Baut man halt in der Treiberschicht ein und gut ist. Ich sehe da keine sonderliche Komplexität, zumal man ja auch nur das abschalten muß, was man selber mal angeschaltet hat. Darüberhinaus darf x86 sicherlich als sehr komplex gelten, und trotzdem ist der Linuxkernel in C - und der Kernel ist komplexer als alles, was unsereins je embedded tun wird.
> Und genau deswegen wird es auch weiterhin einfache Controller geben, > weil es einen Industriebedarf gibt, daß man leicht reviewbaren Code > innerhalb der Anforderungen erstellen kann. Das sehe ich auch so. Als "Helfer" für größere Computer sehe ich bei den "kleinen" Mikrocontrollern noch eine lange Zukunft. Ich denke da an so Sachen wie Eingabegeräte, Laderegler, Timer, Verbrauchszähler, und viel Kleinzeug im Bereich der Maschinensteuerungen.
Jörg W. schrieb: > Zumindest in C sind sie das: du darfst im eigenen Code beispielsweise > eben keine eigene printf-Implementierung haben,
1 | int printf(char *str) |
2 | {
|
3 | return 0; |
4 | }
|
5 | |
6 | int main(void) |
7 | {
|
8 | return printf("Hello, Word!"); |
9 | }
|
...compiliert und linkt ohne Fehlermeldungen mit VC und GCC.
:
Bearbeitet durch User
Torsten R. schrieb: > Operatoren werden in C++ eigentlich "relativ" selten verwendet Gelegentlich finde ich sie schon sinnvoll. Das verlässt natürlich jetzt eher das Embedded-Thema, aber von einer String-Klasse würde ich schon erwarten, dass man mit string1 + string2 die Verkettung beider Strings als Ergebnis erhält – in reinem C war ja das Fehlen einer derart intuitiven String-Verarbeitung immer ein Kritikpunkt. Aber man kann natürlich in jeder Sprache Unfug zimmern, wenn man es drauf anlegt.
Eric B. schrieb: > ...compiliert und linkt ohne Fehlermeldungen mit VC und GCC.
1 | foo.c:1:5: warning: conflicting types for built-in function ‘printf’ [enabled by default] |
2 | int printf(char *str) |
3 | ^ |
4 | foo.c: In function ‘printf’: |
5 | foo.c:1:18: warning: unused parameter ‘str’ [-Wunused-parameter] |
6 | int printf(char *str) |
7 | ^ |
Naja. Ändert nichts daran, dass der Standard es so sieht, dass printf ein Bestandteil der Sprache ist, und darum ging's ja. Letztlich bestätigt der Compiler das ja auch durch sein "built-in function ‘printf’" auch, dass er über diese Funktion Vorwissen besitzt, wie sie auszusehen hätte.
:
Bearbeitet durch Moderator
Stefan U. schrieb: > Na dann schalte mal bei einem noch relativ schlanken STM32F103 alles > abschaltbare ab (außer Wake-Up per externem Signal) und vergleiche die > Stromaufnahme mit irgendeinem beliebigen AVR oder PIC. Dafür musstest du jetzt auch den Low cost controller von stm heraussuchen, der ein absoluter stromfresser ist. Gute arm-Controller haben einen Stromverbrauch von <100uA / MHz und wenige uA im sleep. Schau z.B. mal bei silabs efm32 Serie vorbei. Solange avrs nicht im sleep sind Verbrauchern die übrigens deutlich mehr als die meistens Arms. Operatoren bieten sich immer an wenn man neue mathematische Datentypen benötigt. Beispielsweise biginteger, Vektoren, quaternionen, Matrizen. Ich hab vor kurzem in Java gekotzt, weil ein Algorithmus mit ungefähr 20 Operationen schon nicht mehr normal lesbar war.
avr schrieb: > deutlich mehr als die meistens Arms Naja, eine maßlose Übertreibung: die meisten ARMs dürften keine Cortex-M sein, sondern größere Boliden … aber selbst gegen Cortex-M ist die Aussage nicht völlig korrekt. Der ARM wird dann besser, wenn wirklich groß was zu rechnen ist, das ist unstrittig.
> Schau z.B. mal bei silabs efm32 Serie vorbei.
Genau die hab ich im Einsatz. :-)
Und jetzt ueberlegt mal wie vergleichbares in ein paar Jahren aussieht.
Die Entwicklung bleibt ja nicht stehen. Man kann derzeit in C arbeiten
und muss es auch weil es nunmal einfach Standard ist. Aber mit jedem
Jahr wird der Wunsch groesser das etwas besseres gaebe. Ich hab z.b mit
interesse go/golang angeschaut. Leider nur bis zu der Stelle mit dem
garbage collector, seufz. Aber man darf ja hoffen das nochmal was
kommt...
Olaf
Jörg W. schrieb: > foo.c:1:18: warning: unused parameter ‘str’ [-Wunused-parameter] > int printf(char *str) > Naja. Interessant:
1 | D:\Temp>cl -Wall printf.c |
2 | Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86 |
3 | Copyright (C) Microsoft Corporation. All rights reserved. |
4 | |
5 | printf.c |
6 | Microsoft (R) Incremental Linker Version 14.00.24215.1 |
7 | Copyright (C) Microsoft Corporation. All rights reserved. |
8 | |
9 | /out:printf.exe |
10 | printf.obj |
11 | |
12 | D:\Temp> _ |
Wilhelm M. schrieb: > Nop schrieb: >> Was allerdings in C holprig ist, sind generische Datenstrukturen. Der >> Library-Quicksort muß für jeden Vergleich einen Funktionsaufruf machen, >> der nichtmal inline-fähig ist. C-Qsort ist daher ziemlich lahm. […] >> >> In C++ ist das kein Problem. Man braucht keine expliziten Funktionen >> mehrfach hinschreiben und hat trotzdem nicht diesen indirekten >> Funktionsaufruf für die Vergleiche. >> >> Frage: Angenommen, man will denselben Sortieralgorithmus auf zwei >> verschiedene Datenstrukturen anwenden in C++, was fällt bei C++ dann am >> Ende in Maschinencode raus? Sind das auch separate Funktionen, also von >> der Codegröße her dasselbe wie mit C und separatem Hinschreiben? > > Du wetterst in Deinen obigen Beiträgen so gegen C++, aber hast Dich > offenbar noch nicht wirklich damit befasst! > Schau mal bei template-Instanziierung nach ;-) Er spricht aber einen wichtigen Punkt an: Die sort-Funktion ist ja im Vergleich zu den meisten anderen Template- Funktionen der Standardbibliothek eine recht große Funktion, weswegen man sich bei mehreren Instanzen und beschränktem Programmspeicher zumindest einmal kurz Gedanken machen sollte, wieviel eine Instanz von sort tatsächlich in etwa belegt. Wüsstest du es auf Anhieb? Oder was würdest du schätzen? Ich habe mal nachgeschaut: Es sind um die 1kB, abhängig vom verwendeten Datentyp, der Vergleichsfunktion und den Optimierungsoptionen des Compilers. Will man also nur Int-Vektoren sortieren, ist der Speicherbedarf in etwa gleich wie bei qsort. Hat man zusätzlich noch einen zu sortierenden Double-Vektor, wird ein weiteres kB belegt. Will man an einer anderen Stelle die beiden Vektoren in ab- statt aufsteigender Reihenfolge sortieren, kommt jeweils noch ein kB hinzu. Selbst für das Sortieren eines std::array, dessen Nutzdaten in derselben Form vorliegen wie beim std::vector, wird eine neue Instanz von sort anlegt, d.h. noch ein kB verbraucht. Bei einem PC mit ein paar GB Hauptspeicher fallen selbst 1000 Instanzen von sort nicht ins Gewicht, auf einem kleinen bis mittelgroßen µC aber schon. Das spricht nicht grundsätzlich gegen den Einsatz C++ auf µCs, denn man hat ja auch in C++ nach wie vor Zugriff auf die qsort-Funktion. Das Beispiel zeigt aber, dass man bei der Programmierung in C++ unter Ressourcenbeschränkungen schon ziemlich genau wissen muss, was man tut bzw. wie der Compiler den Quellcode umsetzt. Wenn man nun jedem neuen, noch nicht so erfahrenen Mitglied einer Entwicklerguppe erklären muss, was es bei der C++-Programmierung auf µCs alles zu beachten gibt, wendet man dafür u.U. mehr Zeit auf als wenn man einfach bei der etwas weniger produktiven C-Programmierung bleibt.
Jörg W. schrieb: > avr schrieb: >> deutlich mehr als die meistens Arms > > Naja, eine maßlose Übertreibung: die meisten ARMs dürften keine > Cortex-M sein, sondern größere Boliden … aber selbst gegen Cortex-M > ist die Aussage nicht völlig korrekt. Der ARM wird dann besser, wenn > wirklich groß was zu rechnen ist, das ist unstrittig. Ja, ich meinte eigentlich die Cortex-M Reihe. Dort verbrauchen die Controller eigentlich alle weniger µA/MHz. Die Avrs bieten Vorteile, wenn wirklich fast nichts zu rechnen ist. Aber selbst hier gewinnen sie gegen einen auf Stromverbrauch getrimmten M0+ kaum etwas.
avr schrieb: > Aber selbst hier gewinnen sie gegen einen auf Stromverbrauch getrimmten > M0+ kaum etwas. Yep, Cortex-M0+ sind in der Tat in dieser Hinsicht interessant. Wenn man sie dann noch als 5-V-Version hat (bspw. SAMC21), dann hat man auch diesen bereich noch abgedeckt.
Yalu X. schrieb: > Er spricht aber einen wichtigen Punkt an: > > Die sort-Funktion ist ja im Vergleich zu den meisten anderen Template- > Funktionen der Standardbibliothek eine recht große Funktion, weswegen > man sich bei mehreren Instanzen und beschränktem Programmspeicher > zumindest einmal kurz Gedanken machen sollte, wieviel eine Instanz von > sort tatsächlich in etwa belegt. > > Wüsstest du es auf Anhieb? Oder was würdest du schätzen? > > Ich habe mal nachgeschaut: Es sind um die 1kB, abhängig vom verwendeten > Datentyp, der Vergleichsfunktion und den Optimierungsoptionen des > Compilers. Für welche Architektur hast Du es probiert?
Wird Zeit daß endlich mal jemand Fortran-2008 Compiler für µCs implementiert
Der Andere schrieb: > Wird Zeit daß endlich mal jemand Fortran-2008 Compiler für µCs > implementiert Wenn du einen Cortex-M7 mit 32/64-bit-FPU hast, warum nicht? ;-)
Jörg W. schrieb: > Ändert nichts daran, dass der Standard es so sieht, dass printf ein > Bestandteil der Sprache ist, und darum ging's ja. Letztlich bestätigt > der Compiler das ja auch durch sein "built-in function ‘printf’" auch, > dass er über diese Funktion Vorwissen besitzt, wie sie auszusehen > hätte. Habe es noch mal probiert mit GCC und der meckert tatsächlich. Anderenseids meckert er auch wenn ich das selbstgebackene printf einfach weglasse:
1 | /*int printf(char *str)
|
2 | {
|
3 | return str != (char *) 0;
|
4 | }*/
|
5 | |
6 | int main(void) |
7 | {
|
8 | return printf("Hello, World!"); |
9 | }
|
1 | D:\Temp>gcc printf.c |
2 | printf.c: In function 'main': |
3 | printf.c:8:10: warning: implicit declaration of function 'printf' [-Wimplicit-function-declaration] |
4 | return printf("Hello, World!"); |
5 | ^ |
6 | printf.c:8:10: warning: incompatible implicit declaration of built-in function 'printf' |
7 | printf.c:8:10: note: include '<stdio.h>' or provide a declaration of 'printf' |
Also so ganz und komplett built-in ist es auch nicht...
Die Deklaration von printf() befindet sich in stdio.h - wenn du die nicht einbindest, bekommst du eine inkompatible Deklaration. Dennoch ist dem Compiler printf() bekannt, was nicht so sein dürfte, wenn es nicht zum Standard gehörte.
Jörg W. schrieb: > Wenn du einen Cortex-M7 mit 32/64-bit-FPU hast, warum nicht? ;-) Warum, als Fortran entwickelt wurde, hatte ein IBM Mainframe weniger Rechenleistung. Ein heutiger 8bitter hat dieselbe Rechenleistung wie ein PC-XT. Und selbst heute sind anspruchsvolle Mathebibliotheken, die in C++ und Phyton benutzt werden oft genug noch in Fortran geschrieben. Gut ich gebe zu der Beitrag war nicht ganz erst gemeint, aber als kleiner Weckruf für die streitenden Ideologen gedacht. :-)
Wilhelm M. schrieb: > Für welche Architektur hast Du es probiert? Entschuldigung, das wollte ich noch schreiben, habe es aber vergessen: Es ist ein Notebook mit i7-CPU und GCC. Etwas anderes habe ich nicht zum Testen da.
S. R. schrieb: > Dennoch ist dem Compiler printf() bekannt, was nicht so sein dürfte, > wenn es nicht zum Standard gehörte. Aber ein bisschen schizophren ist es schon. Der Compiler kennt printf() und auch die dazu gehörende Deklaration; sonst könnte er nicht anmeckern, dass ich eine andere Deklaration oder Definition verwende als was er kennt. Dennoch muss ich händisch (oder per #include) die Funktion deklarieren, und zwar genau so wie der Compiler sie schon kennt, um ihn zufrieden zu stellen? (Wo ist c-hater wenn man ihn braucht? ;-D)
Eric B. schrieb: > S. R. schrieb: >> Dennoch ist dem Compiler printf() bekannt, was nicht so sein dürfte, >> wenn es nicht zum Standard gehörte. > > Aber ein bisschen schizophren ist es schon. Der Compiler kennt printf() > und auch die dazu gehörende Deklaration; sonst könnte er nicht > anmeckern, dass ich eine andere Deklaration oder Definition verwende als > was er kennt. Dennoch muss ich händisch (oder per #include) die Funktion > deklarieren, und zwar genau so wie der Compiler sie schon kennt, um ihn > zufrieden zu stellen? In C hat jede(!) Funktion ohne Prototyp den Rückegabetyp int und eine beliebige Parameterliste.
Yalu X. schrieb: > Wilhelm M. schrieb: >> Für welche Architektur hast Du es probiert? > > Entschuldigung, das wollte ich noch schreiben, habe es aber vergessen: > > Es ist ein Notebook mit i7-CPU und GCC. Etwas anderes habe ich nicht zum > Testen da. Habs gerade auf einem AVR getestet:
1 | 00000146 00000220 W void quickSort<unsigned char, 100u>(std::array<unsigned char, 100u>&, unsigned int, unsigned int) |
2 | 00000366 00000294 W void quickSort<unsigned int, 100u>(std::array<unsigned int, 100u>&, unsigned int, unsigned int) |
wobei das natürlich nicht die Version der libstdc++ ist. Also für 8-Bit: 220-Bytes und für 16-Bit 294 Bytes.
Dem gebenüber qsort() für uint8_t:
1 | 00000146 00000014 W int less<unsigned char>(void const*, void const*) |
2 | 00000198 00000040 t swapfunc |
3 | 00000238 00000106 t med3 |
4 | 00000344 00000730 T qsort |
5 | 00001074 00000040 T __udivmodhi4 |
macht zusammen 930 Bytes (wobei dies natürlich fast (bis auf less()) unabhängig vom zu sortierenden DT ist).
Wilhelm M. schrieb: > Habs gerade auf einem AVR getestet: [...] > Also für 8-Bit: 220-Bytes und für 16-Bit 294 Bytes. Eine unbenannte Version ist also kleiner als die der Standardbibliothek. Das ist zwar schön, aber komplett am Thema vorbei. Der Punkt ist nämlich, dass deine Template-Variante für 8-Bit und 16-Bit schon 514 Byte braucht. Noch 32-Bit dazu, bist du vermutlich bei 2 KB. Weil du dann schon drei Quicksorts in deinem Code hast. Die C-Version kommt mit genau einem aus (plus drei trivialen Vergleichsfunktionen) und explodiert in der Größe eben nicht, wenn man sie für verschiedene Datentypen benutzt.
H.J.Gebhardt schrieb: > Sheeva P. schrieb: >> und wie jedes mächtige Feature kann sie auch >> mißbraucht werden. Aber das ist dann kein Argument gegen das Feature, >> sondern erstens eines gegen den, der sie mißbraucht, und zweitens gegen >> seinen Code. > > Ganz klar, bei soviel technokratischer Sichtweise ist natürlich *immer* > der programmierende Mensch "schuld", nie die Programmiersprache. Welchen Teil von "schlechten, unlesbaden und unverständlichen Code kann man in jeder Sprache schreiben" hast Du denn nicht verstanden? Wenn jemand sein Werkzeug nicht beherrscht, ist das nicht das Werkzeug schuld. Es kämme doch auch niemand auf die Idee, einer Badehose vorzuwerfen, daß ihr Träger nicht schwimmen kann... jedenfalls niemand, der noch alle Latten am Zaun hat.
Stefan U. schrieb: > Dagegen spricht, dass µC in der Regel keine so ausgefuchste > Speicherverwaltung haben, wie die ausgewachsenen Server Betriebssysteme. > In Kombination mit knapp bemessenem RAM kommst man schnell zu einem > Out-Of-Memory wegen Heap-Fragmentierung. > > Also "durchgängig" ist hier nicht passend. Man kann C++ auf > Mikrocontrollern verwenden, aber nur eingeschränkt. C++ enthält einige Vereinfachungen für die dynamische Speicherverwaltung -- die benutzt aber auch in C kaum jemand auf Mikrocontrollern, aus denselben von Dir genannten Gründen. Deiner Argumentation folgend müßte man dann also sagen, daß auch C "nur eingeschränkt" auf Mikrocontrollern verwendet werden kann. Am Ende läuft die Argumentation dann auf die Frage hinaus, ob C++ nur dann "das einzig Wahre C++" (tm) ist, wenn man alle seine Features benutzt.
Nop schrieb: > Sheeva P. schrieb: >> Doch, genau so ist es. > > Ja gut, insofern habe ich mich da lax ausgedrückt: es ist nicht so, daß > er es aus Geschmacksgründen oder emotionalen Befindlichkeiten heraus > nicht mag, Doch, genau so ist es. > sondern er lehnt es aus guten Gründen ab. Er faselt von "horrible crap" für "substandard programmers". Wenn Du das für "gute Gründe" hälst, dann haben wir beide ein sehr unterschiedliches Verständnis davon, was "gute Gründe" sind. Sachliche Argumente gegen C++ habe ich von Linus jedenfalls keine gelesen oder gehört. > Während Torvalds mit dem Linuxkernel und auch mit Git immerhin relevante > Projekte vorzeigen kann? Linus Torvalds hat meines Wissens bislang weder ein Industrie-, noch ein embedeed Projekt gemacht. Und, soweit ich weiß, auch noch kein C++-Projekt. Warum sollte ausgerechnet er dazu berufen sein, die einzig wahre Wahrheit über C++ oder embedded Projekte zu äußern? Ein Blinder redet über Farben, und Du beziehst Dich nur darauf, weil es Dir gerade in den Kram paßt. > Doch, weil man Reviews dann nicht mehr lokal machen kann, denn C++ ist > sehr kontextabhängig. Jedes popelige Pluszeichen kann diverse Additionen > in Schleifen bedeuten. Jeder elementare Operator ist möglicherweise ein > Funktionsaufruf, aber man sieht an der Stelle nicht, welche Funktion > aufgerufen wird. Dazu muß man sich dann erstmal durch weitere Dateien > wühlen. Dann darf man auch in C keine Funktionen benutzen, denn schließlich muß unser Reviewer dann in anderen Dateien schauen, was die Funktion tut. Die Überladung von Operatoren benutzen fähige Entwickler natürlich nur, wenn ihre Funktion offensichtlich ist. > Finde ich nicht. Es ist halt eine völlig andere Sichtweise. Sie erklärt > auch, wieso das Anpreisen von noch mehr Features nicht überzeugt, im > Gegenteil. Was Dich nicht überzeugt, finden andere ziemlich gut.
Eric B. schrieb: > Hm, da bin ich andere Meinung. Auch wenn in der Standard eine ganze > Latte an Bibiliotheken beschrieben wird, die mitgeliefert werden soll, > sind sie nicht Teil der Sprache: ich muss als Programmierer dem Compiler > mitteilen, (über #include o.Ä.) dass er bitteschön irgendwelche Typen, > Funktionen usw. interpretieren soll. Der Standard definiert die Sprache. Alles, was im Standard steht, ist damit auch Bestandteil der Sprache, unabhängig davon, ob diese Sprachfeatures nun über Bibliotheken und Header aktiviert werden.
Intermediate Summary Die x-te Zankerei um das Geschwisterpaar "C/C++" ist hier trotz der Erbsenzählerei ziemlich sachlich und es hat auch etliche informative und lehrreiche Häppchen dabei. (das sollte trotz des heiklen Themas ein Lob sein) M.M.n. wird aber an der Fragestellung des TOs vorbeidiskutiert. Was für eine Aufgabe soll mit dem gut ausgestatteten uC denn erledigt werden? Was hat dieser dann zu rechnen und sortieren? Und wieviel davon? M.M.n. geben die Antworten auf diese Fragen den entscheidenden Richtungshinweis für die Programmiersprache. Ich konkretisiere mit (hoffentlich representativen) Beispielen. Ein Apparat mit ein paar Schnittstellen dessen Aufgabe im Wesentlichen "store&forward", allenfalls etwas Protokollumsetzungen ist, kann durchaus "viel" FLASH (Protokollcode) und RAM (Datenpuffer) erfordern, hat aber kaum was zu rechnen (Numbercrunching) und die Komplexität seiner Firmware/Datenstrukturen wird maximal ein "beschedenes" Niveau erreichen. Da könnte also fast BASIC, 'tschuldigung: C reichen. Anderseits kann ein intelligentes Messgerät (1 Liter Volumen, an Hutschiene, ~5W Leistungs = Embedded), welches 2-3 physikalische Umweltgrössen indirekt erfasst + zur Zeit korreliert (ja: RealTime) und über zu seinem Einsatzort spezifischen, flexibel konfigurierbare Angaben, direkt aber aufwändig umrechnet in bloss eine einzige domainspezifische Kenngrösse + eine Handvoll Alarme (Relaiskontakte) es erfordern dass wegen der hohen Integration diverse Libraries (Linearalgebra, Geometrie im Raum, Parser f. Konfigurationsdatensprache, lokaler Interpreter f. Scriptsprache zwecks ad-hoc Funktionalitätsfinetuning) zwingend dynamische Speicherverwaltung unumgänglich ist. Hier geben eher die zur Problemdomain bereits bewährten Libraries resp. deren vorhandenen/fehlenden Sprachbindings den Ton zur Programmiersprachenwahl an. Und es soll bitte eine HOCHsprache sein. Dann vermisse ich den Hinweis dass der in Embeddedkreisen so hochgehaltenen Zwang zur Ressourcenknappheit meist stärker durch hohe bis sehr hohe zu produzierenden Stückzahlen diktiert wird, als durch das Miniaturisieren des Endproduktes an sich. (echte Miniaturisierungskosten werden selten in Projekten akzeptiert) Das drückt dann eher die Tendenz richtung C. Ja, die Wechselwirkung C/C++ zu Ausbildungsniveau der MA zu Projektanforderungen UND die unzaehligen, sich immer wiederholenden Threads wie dieser, bestärkten mich wiederholend in folgenden 2 Meinungen: - echt gute (Embedded-)Programmier-Cracks sind schwer zu finden, egal ob C oder C++; das meisste ist menschliches Mittelmass (ist unsicher, trifft strategische/architektonische Fehlentscheidungen, macht laufend diverse Fehler). Achtung: ich Stufe mich auch bei letzteren ein. Die ganz "coolen Oberhechte" können es nichtmal bei "in flagranti erwischt" zugeben, die müssten einen Doktortitel alleine ihres Benehmens wegen aufgezwungen bekommen... - zur Wahrnehmung der vermeintlichen "guten Eignung" von C/C++ wg. allgegenwärtiger Verbreitung (nicht nur Embedded) trägt das viele Wiederholen der immer gleichen Fehler bei: entsprechend füllen sich Foren, Blogs, Kursangebote, das Angebot an Bücher/Tutorials/etc. Wären die Programmiersprachen C/C++ echt gut so würden sie viele bekannte Stolperfallen gar nicht bieten (damit sie intrinsisch gemieden wären). Zuletzt noch eine Ergänzung zum Komplexitätsvergleich oben, der auf den Umfang der Standards basiert. Meine Lieblingsgrösse ist der Umfang der Sprachesyntax in EBNF: - Modula-2 passt auf 1 A4 Blatt, dabei bleiben keine "interpretation is left to the compiler implementor" über; (na gut, ist bloss Prozedural) - OO-Erweiterungen zu M2, benötigen nur 1 Handvoll EBNF-Regeln dazu, auch Oberon ist auf wenig mehr als 1 A4 Blatt beschrieben. - Ada belegt über 20 Seiten (Unterscheidung Ada95 oder andere hier nicht relevant) - tja und C/C++, wie umfangreich ist das? (es muss CPP zwingend dazu, denn ohne kann man nicht...) Diese Vergleichgrösse schlägt sich direkt in Komplexität, Grösse, (Fehlerpotential) und Abarbeitungsgeschwindigkeit des Compilers nieder. Ein schlanker und blitzschneller Compiler ist auf einer zeitgemäßer, boliden Entwicklerworkstation nur noch schneller! AUF einen üppig ausgestatteten uC gehört also z.B. Lua, um eine moderne, schlanke ProgrammierHOCHsprache zu nennen (wenn auch beim Design von Lua bewusst Kompromisse im Bezug auf Sprachfeatures eingegangen wurden). Oder MicroPython, ist aber noch ein wenig jung... popcorn hol
Eric B. schrieb: > Aber ein bisschen schizophren ist es schon. Der Compiler kennt printf() > und auch die dazu gehörende Deklaration; Dann lass uns mal die original-Fehlermeldung auseinandernehmen: Jörg W. schrieb: > foo.c:1:5: warning: conflicting types for built-in function ‘printf’ > [enabled by default] Das [enabled by default] ist schon ein Hinweis, dass diese Meldung kein C-Problem ist und der Compiler "zu laut" ist. Er kennt sprintf, um die wenig typsicheren Parameter wenigstens ein bisschen prüfen zu können. Wenn ich ein eigenes, inkompatibles printf baue, dann sollte ich dem Compiler das auch sagen oder auf diesen Komfort verzichten. > int printf(char *str) > ^ > foo.c: In function ‘printf’: > foo.c:1:18: warning: unused parameter ‘str’ [-Wunused-parameter] > int printf(char *str) Das ist ein einfacher "Programmierfehler". str wird ja in der Tat nicht benutz. Meist reicht ein einfaches (void) str; oder so.
Achim S. schrieb: > Das [enabled by default] ist schon ein Hinweis, dass diese Meldung kein > C-Problem ist und der Compiler "zu laut" ist. Nein, es ist ein Hinweis, dass es dafür keiner -Wirgendwas-Option bedarf.
Programmiersprachentheaterintendant schrieb: > Zuletzt noch eine Ergänzung zum Komplexitätsvergleich oben, der auf den > Umfang der Standards basiert. Meine Lieblingsgrösse ist der Umfang der > Sprachesyntax in EBNF: > [...] > - tja und C/C++, wie umfangreich ist das? (es muss CPP zwingend dazu, > denn ohne kann man nicht...) Google hilft, die EBNF für C hat 3 Seiten [1], die für C++ ca. 5 Seiten [2]. [1] https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm [2] http://www-i3.informatik.rwth-aachen.de/tikiwiki/tiki-download_file.php%3FfileId=103
Programmiersprachentheaterintendant schrieb: > Zuletzt noch eine Ergänzung zum Komplexitätsvergleich oben, der auf den > Umfang der Standards basiert. Meine Lieblingsgrösse ist der Umfang der > Sprachesyntax in EBNF: > - Modula-2 passt auf 1 A4 Blatt, dabei bleiben keine "interpretation > is left to the compiler implementor" über; (na gut, ist bloss > Prozedural) Hast du einen Link dazu? Oder eine Empfehlung, wie stark das Mikroskop eingestellt werden muss, um den Text auf der A4-Seite überhaupt lesen zu können? > Diese Vergleichgrösse schlägt sich direkt in Komplexität, Grösse, > (Fehlerpotential) und Abarbeitungsgeschwindigkeit des Compilers nieder. > Ein schlanker und blitzschneller Compiler ist auf einer zeitgemäßer, > boliden Entwicklerworkstation nur noch schneller! Ich sag ja schon immer, dass Lisp die beste aller Programmiersprachen ist. Da passt die EBNF in großer Schrift auf die Handfläche, so dass man sie immer mit dabei hat:
1 | program = s-expr; |
2 | s-expr = atom |
3 | | "(" s-expr "." s-expr ")" |
4 | | "(" { s-expr } ")"; |
;-) Edit: Da fällt mir gerade ein, dass es ja noch eine bessere Programmiersprache als Lisp gibt, nämlich Forth:
1 | program = { word }; |
:
Bearbeitet durch Moderator
Yalu X. schrieb: > Ich sag ja schon immer, dass Lisp die beste aller Programmiersprachen > ist. Da passt die EBNF in großer Schrift auf die Handfläche, so dass man > sie immer mit dabei hat: > > >
1 | > program = s-expr; |
2 | > s-expr = atom |
3 | > | "(" s-expr "." s-expr ")" |
4 | > | "(" { s-expr } ")"; |
5 | > |
Lisp... warte, war das nicht dieser als höhere Sprache getarnte Binärcode, bei dem "(" für eine 0, ")" für eine 1 steht -- manchmal, je nach Dialekt, auch umgekehrt? ;-)
Sheeva P. schrieb: > Sachliche Argumente gegen C++ habe ich von Linus jedenfalls keine gelesen oder gehört. Eine Brille oder ein Hörgerät wären eine Überlegung wert. ;-) > Und, soweit ich weiß, auch noch kein C++-Projekt. Auch das liegt nicht an Torvalds. > Ein Blinder redet über Farben Das hat bei Dan Saks keinen gestört. Darüberhinaus hat er genau welche Großprojekte vorzuweisen? > Dann darf man auch in C keine Funktionen benutzen Der Punkt war nicht, daß eine Funktionalität ausgeführt wird. > Die Überladung von Operatoren benutzen fähige Entwickler natürlich nur, wenn ihre Funktion offensichtlich ist. Von irreführender Überladung war nicht die Rede. > Was Dich nicht überzeugt, finden andere ziemlich gut. Weswegen sogar ein C++-Proponent eingesteht, daß C++ embedded auf dem absteigenden Ast ist. Könnte natürlich auch ökonomisch begründet sein. Du wirst, ceterum paribus, für dasselbe Ausmaß an Qualifikation in einer wesentlich komplexeren Sprache nunmal deutlich mehr zahlen müssen. Alternativ kriegst Du für denselben Preis eben weniger Qualifikation. Das rechnet sich in dem Moment, wo man ein Projekt hat, das in C wesentlich länger dauern würde. Insbesondere GUI und Simulationen sehe ich hier. Das sind aber nicht die typischen embedded-Geschichten.
Jörg W. schrieb: > aber von einer String-Klasse würde > ich schon erwarten, dass man mit string1 + string2 die Verkettung > beider Strings als Ergebnis erhält – Das tolle an der Stringaddition ist, dass 1000€ und 100€ schon reichen um Millionär zu sein. "1000"+"100" = "1000100" oder sogar schon 7€: "1"+"1"+"1"+"1"+"1"+"1"+"1" = "1111111" Sorry, aber meine Intuition sagt da, dass Verkettung etwas ganz anderes ist als Addition.
> > Hast du einen Link dazu? Oder eine Empfehlung, wie stark das Mikroskop > eingestellt werden muss, um den Text auf der A4-Seite überhaupt lesen zu > können? ISBN 978-3-642-83565-0 T:"Programming in Modula-2" A:"N. Wirth" Soll aber nur ein Beispiel sein, konkrete Implementationen, ggfs mit OO-Erweiterungen, weichen ein wenig davon ab. > >> Diese Vergleichgrösse schlägt sich direkt in Komplexität, Grösse, >> (Fehlerpotential) und Abarbeitungsgeschwindigkeit des Compilers nieder. >> Ein schlanker und blitzschneller Compiler ist auf einer zeitgemäßer, >> boliden Entwicklerworkstation nur noch schneller! > > Ich sag ja schon immer, dass Lisp die beste aller Programmiersprachen > ist. : : > Da fällt mir gerade ein, dass es ja noch eine bessere Programmiersprache > als Lisp gibt, nämlich Forth: Sehr schön: mit einem offenen Blick über den Gartenzaun der Grauen C/C++ Welt wird die diskussion Farbig. :-) Mit Forth landet man auch direkt wieder zentriert im Themengebiet uC/RT/Embedded.
Ergänzend zu meinen Zahlen von gestern hier eine Zusammenstellung (s.a. Anhang). Wenn ich nochmal Zeit finde und Luste dazu habe werde ich die Zahlen auch noch für ARM-Cortex-Mx (dazu brauche ich aber HW) und Intel Core i7 zusammenstellen.
> > Lisp... warte, war das nicht dieser als höhere Sprache getarnte > Binärcode, bei dem "(" für eine 0, ")" für eine 1 steht -- manchmal, je > nach Dialekt, auch umgekehrt? ;-) Polymorphismus und Dynamic Typing (pun intended ;) gab es bereits vor der EDV auf Schreibmaschinen: da wurden ganze Datenbanken mit 'l' für 1 und 'O' für 0 erstellt ;-D
Jobst Q. schrieb: > Das tolle an der Stringaddition ist, dass 1000€ und 100€ schon reichen > um Millionär zu sein. Nein, weil 1 und '1' logisch völlig verschiedene Dinge sind. Programmiersprachentheaterintendant schrieb: > Dynamic Typing (pun intended ;) LOL der war gut! Wilhelm M. schrieb: > Ergänzend zu meinen Zahlen von gestern hier eine Zusammenstellung (s.a. > Anhang). Embedded nutzt qsort oftmals nicht Quicksort, weil man mit rekursiven Algorithmen u.U. in Stackprobleme rennt. Für die typischen Listenlängen von vielleicht 100 Elementen oder so, die man auf µCs mal haben kann, ist Shellsort wohl die beste Lösung (Ciura-Sequenz nehmen). Oder Insertion Sort, bei sehr kurzen Listen. Oder Selection Sort, wenn man nur das maximale (oder minimale) Element benötigt. Siehe auch hier: http://embeddedgurus.com/stack-overflow/2009/03/sorting-in-embedded-systems/ Auch ein Grund, wieso ich qsort nicht nutze, weil man nie weiß, was genau da unter der Haube passiert. Die Ergebnisse sollten zwar äquivalent sein, aber wenn es doppelte Sortierschlüssel gibt, weichen sie u.U. dennoch ab. Das macht Debugging und Portierung unnötig schwierig.
Nop schrieb: > Wilhelm M. schrieb: > >> Ergänzend zu meinen Zahlen von gestern hier eine Zusammenstellung (s.a. >> Anhang). > > Embedded nutzt qsort oftmals nicht Quicksort, weil man mit rekursiven > Algorithmen u.U. in Stackprobleme rennt. Nun, damit wollte ich ja auch gar nicht Quicksort propagieren, sondern einfach nur u.a. einen Vergleich zu (hier) avr-libc herstellen - völlig wertfrei. Und weil nun die libc ein Quicksort (mit Stackbegrenzung und Umschaltung auf Insertionsort) verwendet, habe ich es als Template genauso gemacht und die anderen Realisierungen von Quicksort dazu gepackt. > Auch ein Grund, wieso ich qsort nicht nutze, weil man nie weiß, was > genau da unter der Haube passiert. Die Ergebnisse sollten zwar > äquivalent sein, aber wenn es doppelte Sortierschlüssel gibt, weichen > sie u.U. dennoch ab. Das macht Debugging und Portierung unnötig > schwierig. Die Ergebnisse sind nur gleich, wenn es stabile Sortierverfahren sind.
Jobst Q. schrieb: > Jörg W. schrieb: >> aber von einer String-Klasse würde >> ich schon erwarten, dass man mit string1 + string2 die Verkettung >> beider Strings als Ergebnis erhält – > > Das tolle an der Stringaddition ist, dass 1000€ und 100€ schon reichen > um Millionär zu sein. > > "1000"+"100" = "1000100" Schöner sind doch die Sprachen, bei denen die Operation nicht vom Typ sondern vom Inhalt abhängt: "x"+"1" -> "x1" "1"+"1" -> 2 "1"+"x" -> Exception: x is not a number Das nenn ich wirklich konsistent.
Wilhelm M. schrieb: > Nun, damit wollte ich ja auch gar nicht Quicksort propagieren, sondern > einfach nur u.a. einen Vergleich zu (hier) avr-libc herstellen - völlig > wertfrei. Ah, so herum. > Die Ergebnisse sind nur gleich, wenn es stabile Sortierverfahren sind. Sie sind auch gleich, wenn man jedesmal exakt dasselbe instabile Sortierverfahren auf denselben Daten anwendet. Derselbe Shellsort auf einem ARM wird eine gegebene Liste genauso sortieren wie auf x86. Hingegen qsort kann in Wahrheit sonstwas sein, und ist es embedded auch oft. Das macht natürlich dann auch Vergleiche mit Codegröße und Geschwindigkeit schwierig, und Stackbedarf sowieso.
Nop schrieb: > Wilhelm M. schrieb: > >> Nun, damit wollte ich ja auch gar nicht Quicksort propagieren, sondern >> einfach nur u.a. einen Vergleich zu (hier) avr-libc herstellen - völlig >> wertfrei. > > Ah, so herum. > >> Die Ergebnisse sind nur gleich, wenn es stabile Sortierverfahren sind. > > Sie sind auch gleich, wenn man jedesmal exakt dasselbe instabile > Sortierverfahren auf denselben Daten anwendet. Derselbe Shellsort auf > einem ARM wird eine gegebene Liste genauso sortieren wie auf x86. Welcher (derselbe!) Quicksort wird denn dieselben(!) Daten auf unterschiedlichen Architekturen unterschiedliche sortieren? (Irgendwelche DT-Begrenzungen ausgeschlossen).
Jobst Q. schrieb: > Das tolle an der Stringaddition ist, dass 1000€ und 100€ schon reichen > um Millionär zu sein. > > "1000"+"100" = "1000100" > ... > Sorry, aber meine Intuition sagt da, dass Verkettung etwas ganz anderes > ist als Addition. Wenn du so denkst (was ich durchaus nachvollziehen kann), dann ist Haskell dein Freund :) Dort sind die Operatoren "+", "-" und "*" den Zahlen vorbehalten (genauer gesagt, der Typklasse Num, die in der Algebra grob dem Ring entspricht). Für Strings und Listen gibt es "++" oder (allgemeiner, da auf beliebige Monoide anwendbar) `mappend`. Anders als in C++ unterliegt das Überladen von Operatoren gewissen Regeln, um allzu üblem Überladungswildwuchs vorzubeugen. Wobei das Stringverkettungs-"+" in C++ für mich ja gerade noch akzeptabel ist, aber mit dem Missbrauch der Bitshift- als Stream-Operatoren ist für mich die Grenze des guten Geschmacks erreicht. Sie sind dafür nicht nur logisch, sondern auch in der Operatorrangfolge fehlplatziert und verstoßen damit ganz klar gegen das Prinzip der geringsten Überraschung. Natürlich wäre es in Haskell mit wenig Aufwand möglich, Definitionen der Arithmetikoperatoren für Strings derart zu schreiben, dass, wie von dir erwartet, "1000"+"100" = "1100" und "3" * "4" = "12" ist. Da aber diese Form der String-Arithmetik nicht auf beliebige Strings anwendbar ist und ohnehin kaum gebraucht wird, lässt man es besser bleiben.
Programmiersprachentheaterintendant schrieb: >> Hast du einen Link dazu? Oder eine Empfehlung, wie stark das Mikroskop >> eingestellt werden muss, um den Text auf der A4-Seite überhaupt lesen zu >> können? > > ISBN 978-3-642-83565-0 > T:"Programming in Modula-2" > A:"N. Wirth" Ich habe dieses Buch nicht und kann die entsprechende Seite auch in books.google.com nicht finden. Vermutlich sieht die Syntaxbeschreibung in etwa so aus: https://www.modula2.org/tutor/syntax.php Weil das aber in lesbarer Schriftgröße kaum auf eine A4-Seite passt, hätte mich interessiert, wie es im Original aussieht. Ok, dreispaltig oder mit Weglassen der Zeilenumbrüche in den einzelnen Regeln könnte es vielleicht passen.
Nop schrieb: >> Das tolle an der Stringaddition ist, dass 1000€ und 100€ schon reichen >> um Millionär zu sein. > > Nein, weil 1 und '1' logisch völlig verschiedene Dinge sind. Logisch nicht, es sind beides gültige Darstellungen vom Typ char. Verschieden ist es arithmethisch:'1' ist nicht 1 sondern meistens 49. Aber du hast recht, wenn du "1" statt '1' meinst. Und weil 1 und "1" logisch völlig verschiedene Dinge sind, sind auch Verkettung und Addition völlig verschiedene Dinge. Es gibt eine Stringverkettung, aber keine Stringaddition. Man kann es praktisch finden, für beides denselben Operator zu verwenden, aber es führt auch zur Verwirrung. Ebenso ist das Aufnehmen in eine Liste nicht sinnvoll eine Addition zu nennen. list_add(list, item) ist ähnlich irreführend wie list += item. Treffender wären list_append für unsortierte Listen und list_insert für die etwas intelligenteren Listen.
Wilhelm M. schrieb: > Welcher (derselbe!) Quicksort wird denn dieselben(!) Daten auf > unterschiedlichen Architekturen unterschiedliche sortieren? Gar keiner natürlich, nur ist qsort nicht Quicksort, und schon gar nicht immer derselbe, sondern nur irgendetwas, das sortiert.
Carl D. schrieb: > Schöner sind doch die Sprachen, bei denen die Operation nicht vom Typ > sondern vom Inhalt abhängt: > "x"+"1" -> "x1" > "1"+"1" -> 2 > "1"+"x" -> Exception: x is not a number > > Das nenn ich wirklich konsistent. Wurde das von, oder für K.B. entwickelt?
Heinz V. schrieb: > Carl D. schrieb: >> Schöner sind doch die Sprachen, bei denen die Operation nicht vom Typ >> sondern vom Inhalt abhängt: >> "x"+"1" -> "x1" >> "1"+"1" -> 2 >> "1"+"x" -> Exception: x is not a number >> >> Das nenn ich wirklich konsistent. > > Wurde das von, oder für K.B. entwickelt? Es scheint so.
Wilhelm M. schrieb: >
1 | > auto s = 1_m; |
2 | > auto t = 1_sec; |
3 | >
|
4 | > Velocity = s/t; |
5 | >
|
Schön, da geht dann auch
1 | Velocity = s + t; |
Endlich das tun, was in der Physik nicht geht :-)
Johann L. schrieb: > Wilhelm M. schrieb: >>
1 | >> auto s = 1_m; |
2 | >> auto t = 1_sec; |
3 | >>
|
4 | >> Velocity = s/t; |
5 | >>
|
> > Schön, da geht dann auch > >
1 | Velocity = s + t; |
> > Endlich das tun, was in der Physik nicht geht :-) Hä? Nö.
Johann L. schrieb: > Wilhelm M. schrieb: >>
1 | >> auto s = 1_m; |
2 | >> auto t = 1_sec; |
3 | >>
|
4 | >> Velocity = s/t; |
5 | >>
|
> > Schön, da geht dann auch > >
1 | Velocity = s + t; |
> > Endlich das tun, was in der Physik nicht geht :-) User defined literals können auch eigene Typen zurück geben. Es ist nirgends in Stein gemeißelt, dass s ein Integer ist...
Nop schrieb: > Sheeva P. schrieb: > >> Sachliche Argumente gegen C++ habe ich von Linus jedenfalls keine >> gelesen oder gehört. > > Eine Brille oder ein Hörgerät wären eine Überlegung wert. ;-) Meine Ehefrau sagt sowas auch immer wieder, aber meine Ärzte sagen, daß weder das Eine noch das Andere notwendig sind. Aber da Du ja sachliche Argumente gefunden haben willst, kannst Du sie doch sicherlich zitieren. Vielleicht würde das Deine Argumentation endlich versachlichen, anstatt immer wieder über die Ringstruktur jener Vorurteile zu iterieren, die Du mit den Aussagen von Linus und Dan initialisiert hast. >> Und, soweit ich weiß, auch noch kein C++-Projekt. > > Auch das liegt nicht an Torvalds. An wem denn sonst, am Osterhasen vielleicht? >> Ein Blinder redet über Farben > > Das hat bei Dan Saks keinen gestört. Darüberhinaus hat er genau welche > Großprojekte vorzuweisen? Frag' Dan, seine Kontaktdaten findest Du dort: [1]. >> Dann darf man auch in C keine Funktionen benutzen > > Der Punkt war nicht, daß eine Funktionalität ausgeführt wird. Aber ja, natürlich. Ein überladener Operator ist nichts anderes als eine Funktion, die nur mit einer anderen Syntax aufgerufen wird. Und da einer der Operanden immer ein benutzerdefinierter Datentyp sein muß, sieht jeder Hirni sofort, daß Dein "+"-Operator nicht auf zwei Zahlen angewendet wird, sondern auf Datentypen, die sich normalerweise nicht addieren lassen. Also schaut unser Hirni natürlich nach, was da gemacht wird -- genau wie bei einem "normalen" Funktionsaufruf auch. > Du wirst, ceterum paribus, für dasselbe Ausmaß an Qualifikation in einer > wesentlich komplexeren Sprache nunmal deutlich mehr zahlen müssen. > Alternativ kriegst Du für denselben Preis eben weniger Qualifikation. > > Das rechnet sich in dem Moment, wo man ein Projekt hat, das in C > wesentlich länger dauern würde. Das ist eine sehr kurzsichtige Sichtweise, die alle langfristigen Effekte besserer Codeorganisation, Les- und Wiederverwendbarkeit ignoriert. Klar, kann man machen -- fragt sich nur, wie lange. Nach meiner Erfahrung sind Entwickler und Unternehmen, die sich nicht weiterentwickeln und -bilden wollen, ziemlich bald auf dem Abstellgleis anzutreffen. [1] http://www.dansaks.com/
Torsten R. schrieb: > In Bereichen, wo die Software einen sehr hohen Anteil an der Entwicklung > ausmacht, wird arbeitsteilig gearbeitet. Der E-Techniker macht die > Hardware und SW-Techniker macht die Software. Das ist in der Tat die Krux, sowas geht eben nicht. Der HW-Entwickler hat nicht die Lust, sich mit sowas langweiligen wie GUI und Webinterface auseinander zu setzen und der GUI-Programmierer glänzt wiederum mit völligen Unverständnis der darunter liegenden Hardware. Wir versuchen daher, einen Mittelweg zu nehmen. Der HW-Entwickler macht die HW-nahe Programmierung auf einem einfachen MC mit CAN-Interface (z.B. AT90CAN128) und der GUI-Crack kann sich dann mit den CAN-Kommandos ungeniert austoben, ohne HW zerstören zu können. Er kriegt auch Fehlermeldungen, wenn er falsche Kommandos schickt. Wichtig ist vor allem, der HW-Entwickler bastelt sich auch Kommandos zum Test und Diagnose ein, die dann z.B. über UDP getunnelt werden. Das war immer ein Hauptproblem, wenn der GUI-Progger direkt auf die HW zugegriffen hatte, fehlten sämtlich Diagnosemöglichkeiten. Und Fehlermeldungen landeten in /dev/null.
Vincent H. schrieb: > Johann L. schrieb: >> Wilhelm M. schrieb: >>>
1 | >>> auto s = 1_m; |
2 | >>> auto t = 1_sec; |
3 | >>>
|
4 | >>> Velocity = s/t; |
5 | >>>
|
>> >> Schön, da geht dann auch >> >>
1 | Velocity = s + t; |
>> >> Endlich das tun, was in der Physik nicht geht :-) > > > User defined literals können auch eigene Typen zurück geben. Es ist > nirgends in Stein gemeißelt, dass s ein Integer ist... Da hat ja mal einer mitgedacht: genau so ist es! DAS meine ich mit einer reichen Typisierung durch domänenspezifische Datentypen!
1 | typedef Quantity<1,0,0> Mass; |
2 | typedef Quantity<0,1,0> Length; |
3 | typedef Quantity<0,2,0> Area; |
4 | typedef Quantity<0,3,0> Volume; |
5 | typedef Quantity<0,0,1> Time; |
6 | typedef Quantity<0,1,-1> Speed; |
7 | typedef Quantity<0,1,-2> Acceleration; |
8 | typedef Quantity<0,0,-1> Frequency; |
9 | typedef Quantity<1,1,-2> Force; |
10 | typedef Quantity<1,-1,-2> Pressure; |
Mit dem template Quantity<M,L,T> kann man wie oben das Einheitensystem bauen. Und definiert dann die physikalisch sinnvollen Operationen.
Carl D. schrieb: > Schöner sind doch die Sprachen, bei denen die Operation nicht vom Typ > sondern vom Inhalt abhängt: > "x"+"1" -> "x1" > "1"+"1" -> 2 > "1"+"x" -> Exception: x is not a number > > Das nenn ich wirklich konsistent. Auch schön: Sprachen, die das "x" dann einfach verschlucken... "x" + "1" -> 1 "1" + "1" -> 2 "1" + "x" -> 1
Wilhelm M. schrieb: > Dem gebenüber qsort() für uint8_t: > >
1 | > 00000146 00000014 W int less<unsigned char>(void const*, void const*) |
2 | > 00000198 00000040 t swapfunc |
3 | > 00000238 00000106 t med3 |
4 | > 00000344 00000730 T qsort |
5 | > 00001074 00000040 T __udivmodhi4 |
Das ist jetzt nicht dein Ernst, oder?
Peter D. schrieb: > Torsten R. schrieb: >> In Bereichen, wo die Software einen sehr hohen Anteil an der Entwicklung >> ausmacht, wird arbeitsteilig gearbeitet. Der E-Techniker macht die >> Hardware und SW-Techniker macht die Software. > > Das ist in der Tat die Krux, sowas geht eben nicht. Doch, soetwas geht! ;-) Mehrfach selbest erlebt und dran teilgenommen.
Sheeva P. schrieb: > Aber da Du ja sachliche > Argumente gefunden haben willst, kannst Du sie doch sicherlich zitieren. Es ist doch allgemein bekannt, wenn man nicht nur die belustigenden Teile von Torvalds' Rants liest, daß die sehr wohl versucht haben, ob C++ im Kernel sinnvoll ist. Sicher war C++ damals bei weitem nicht da, wo es heute ist, aber die Grundphilosophie der compiler magic ist nicht weniger, sondern mehr geworden. > Frag' Dan, seine Kontaktdaten findest Du dort: [1]. Wenn Dan etwas wie den Kernel oder Git vorzuweisen hätte, wüßte man das, da braucht man nicht zu fragen. Insbesondere haben sowohl Kernel als auch Git genau die Bedingungen der Industrie - immer wieder wechselnde Programmierer mit schwankender Qualität. Wenn Dan sich hinstellt und von modernem C++ erzählt, drückt er damit auch nur aus, daß Legcy-Code ihm egal ist, er ist kein Maintenance-Programmierer, sondern macht lieber die neuen Systeme (die dann in 10 Jahren zum Alptraum der Maintenance-Programmierer werden). >> Der Punkt war nicht, daß eine Funktionalität ausgeführt wird. > > Aber ja, natürlich. Ein überladener Operator ist nichts anderes als eine > Funktion, die nur mit einer anderen Syntax aufgerufen wird. Eben das ist das Problem: http://www.rachelslabnotes.com/2009/10/the-hidden-cost-of-c/ Torvalds' Rant laufen darauf hinaus, daß er keine Leute im Projekt haben will, die hierin weder ein offenkundiges Problem sehen noch es bei Erklärung als Problem wahrnehmen. Es sieht elegant aus, ist toll hinzuschreiben, aber professionell wird Code viel öfter gelesen als geschrieben. Für den Maintenance-Programmierer danach ist sowas die Hölle. Und es wird noch besser, JEDE Zeile, die in C offensichtlich nichts oder nur Elementares tut, kann in C++ einen riesigen Rattenschwanz im Hintergrund bedeuten. Der wird vor dem Programmierer versteckt. Das kann man als Abstraktion sehen, aber auch als Obfuscation. Ist egal für den Ersteller, aber extrem mies für die Maintenance-Programmierer, und die machen in der Industrie den Löwenanteil aus. Weil man eben nicht dauernd alles neu schreibt, schon weil Firmen dann pleitegehen würden. Dazu hat Joel Spolsky ja auch ein paar interessante Artikel, kennste ja sicher. Insofern spart C++ da Kosten beim Erstellen, aber sobald der Entwickler weg ist, schlagen die Folgekosten umso heftiger zu. Und zwar jedesmal, wenn der Entwickler wechselt. Mag für Dich egal sein, wenn Du selbständig ist und daher Deine Produkte selber betreust. > Also schaut unser Hirni natürlich nach, was da gemacht > wird -- genau wie bei einem "normalen" Funktionsaufruf auch. Siehste, Du nimmst das also nicht als Problem wahr. Deswegen zählst Du zu genau den Leuten, die ein Torvalds aus seinen Projekten schon dadurch vergraulen will, daß er sich für C anstatt für C++ entscheidet. Wobei man da auch in C Sachen verbrechen kann.. ich sag nur die ST-HAL, wo für simples Pin-Toggling Unmengen an Code durchlaufen werden. Es bleibt von der Performance her ähnlich problematisch, aber das Problem kann sich zumindest nicht auch noch hinter oberflächlicher Einfachheit verstecken. > Das ist eine sehr kurzsichtige Sichtweise, die alle langfristigen > Effekte besserer Codeorganisation, Les- und Wiederverwendbarkeit > ignoriert. Als ob das rein durch C++ gegeben wäre - im Gegenteil, weil es noch viel mehr Möglichkeiten gibt, wie man falsch abbiegen kann. Der ganze Code aus der Ära, in der man Vererbung und Hierarchien wie geschnitten Brot in den Code gekippt hat, ist doch einfach geronnene Lava. Zumal auch C++ seine eigene Pasta hat - in dem Fall Ravioli. Muß man alles nicht machen, man kann auch alles in C++ genau richtig machen? Ja. Theoretisch schon. Theoretisch kann man aber auch in C alles richtig machen. > meiner Erfahrung sind Entwickler und Unternehmen, die sich nicht > weiterentwickeln und -bilden wollen, ziemlich bald auf dem Abstellgleis > anzutreffen. Wer jedem Hype hinterherrennt, nur weil's neu ist, macht sich auch nicht besser. Wenn man da wirklich woanders hinwollte, wäre C++ keine Alternative zu C, sondern völlig neue Sprachen, die die Fehler von C++ und Java adressieren. Da tut sich derzeit eine Menge. C++ ist weder neu noch modern, sondern nur einen Hauch weniger veraltet als C. Es ist der Großvater unter den heutigen OOP-Sprachen. Das als modern auszugeben ist ein Brüller, der allenfalls im Vergleich mit dem noch älteren C funktioniert. Und zum Weiterentwickeln hatte ich schon etwas gesagt, daß ich es für sinnvoller halte, sich auf das Domänenwissen zu konzentrieren, weil das im Gegensatz zum Coding Kern-Knowhow ist. Coding wird zusehends ausgelagert. Die Leute in Osteuropa sind sehr fit (Indien sieht eher schlecht aus), und wenn Du künftig mit deren Gehalt konkurrieren möchtest, dann ergibt es strategisch Sinn, sich auf dieses Gebiet zu konzentrieren. Ich konzentriere mich lieber auf andere Sachen und bilde mich insbesondere über den Tellerrand der reinen SW-Entwicklung hinaus. Mehr dahin, was man überhaupt entwickeln sollte; da gibt's beispielsweise in Sachen Usability und Barrierefreiheit eine Menge zu lernen. Überdies sind in meiner industriellen Praxis die weitaus meisten realen Fehler, die ich antreffe, keine C-Fehler - ich entsinne in den letzten zwei Jahren überhaupt keinen direkten. Liegt natürlich auch daran, daß man mit MISRA die fehlerträchtigsten Konstrukte nur dann erlaubt, wenn sie einem gründlichen Review unterzogen wurden. Die natürliche Faulheit führt dazu, daß man sich den Aufwand nur ungern antut. Etwa 25% sind algorithmische Fehler, 75% sind Fehler in der Systemdefinition (die aber korrekt in Code umgesetzt wurde), die erst bei partiellem Systemausfall oder unter pathologischen Bedingungen zum Tragen kommen konnten.
Beitrag #5037862 wurde von einem Moderator gelöscht.
*** schrieb im Beitrag #5037862: > Ohne > unnütz sprachgewaltiges Administrations- und Code Palaver, kein > > Nop schrieb: >> ST-HAL, >> wo für simples Pin-Toggling Unmengen an Code durchlaufen werden Was natürlich nur dann zutrifft, wenn man sein Werkzeug, den Compiler, nicht beherscht. Seit LTO ist das kein Thema mehr.
Beitrag #5037885 wurde von einem Moderator gelöscht.
avr schrieb: > Was natürlich nur dann zutrifft, wenn man sein Werkzeug, den Compiler, > nicht beherscht. Seit LTO ist das kein Thema mehr. Ja, beim Compilieren "-flto" in die Flags zu setzen erfordert natürlich auch eine unglaubliche Kompetenz - mindestens 50% mehr als "-O02". Zumal ich nicht glaube, daß sich die ST-HAL dank LTO wirklich in direkte Registerzugriffe übersetzt. Abgesehen davon sind bei ernsthafteren Projekten keine Compiler-Optimierungen erlaubt, wenn man nicht nachweist, daß der resultierende Binärcode dann noch das ist, was der Programmierer beabsichtigt hat. Der nachweis ist aber dermaßen teuer, daß man ihn praktisch nicht führen kann. Für Consumer-Elektronik ist das natürlich alles egal, die wird aber auch billigst in China zusammengedengelt, auch die Software. Schließlich ist Qualität dabei weder von Auflagen noch vom Kunden gefordert.
Beitrag #5037967 wurde vom Autor gelöscht.
Nop schrieb: ... > Abgesehen davon sind bei ernsthafteren Projekten keine > Compiler-Optimierungen erlaubt, wenn man nicht nachweist, daß der > resultierende Binärcode dann noch das ist, was der Programmierer > beabsichtigt hat. Der nachweis ist aber dermaßen teuer, daß man ihn > praktisch nicht führen kann. Eher was der Programmierer dem Compiler mitteilen wollte. Und da ist eine Sprache klar im Vorteil die mit Typen virtuos umgehen kann.
Carl D. schrieb: > Eher was der Programmierer dem Compiler mitteilen wollte. Und da ist > eine Sprache klar im Vorteil die mit Typen virtuos umgehen kann. Nein, das hat mit Typen wenig zu tun, sondern damit, daß der Compiler ganze Codepassagen wegoptimieren kann, die durchaus wesentlich waren. Das ist natürlich dann ein Fehler im Code (normalerweise). Typensicherheit ist sicherlich nett, betrachte ich aber anhand der Fehler, die mir real so unterkommen, als nebensächlich. Die Fehler wären selbst mit Ada passiert, weil auch Ada keine fehlerhafte Spec abfängt und auch keine algorithmischen Fehler.
Ich finde, soll doch jeder diejenige Werkzeuge verwenden die (für ihn) zum vernünftigen Erfolg führen. Die jeweiligen Randbedingungen, Zugang zu den notwendigen Werkzeugen, Erfahrung und Sprachengewandtheit, die Art der Anwendung und alle andere Faktoren die eine Rolle spielen, bestimmen oft maßgeblich die Art der Lösung dieser Aufgaben. Nichts auf dieser Erde ist perfekt(nicht einmal ich;-) ) Jede Sprache hat ihre Stärke und Schwächen und da so Vieles intrikat voneinander abhängt gibt es sowieso keine "goldene" Lösung des Problems. Letztlich hängt es dann vom Entwickler, die vorhandenen Werkzeuge und dem Druck des Auftraggebers ab, wie es gemacht wird. Und dann, muß man eben (als Entwickler) die Suppe auf Gedeih und Verderb selber auslöffeln. Es hieß ja vor langer Zeit, C wäre ja nur ein verbesserter Assembler. Hardware nahe läßt sich Vieles Resourcen effizient erreichen und ist für knappe uC ideal. Das gilt zum Teil auch für C++, wenn mit Verstand eingesetzt. Auch wenn C heutzutage einen faden Geschmack aufweisen mag und seine bekannten Herausforderungen stellt, wird der Erfahrene trotzdem seine Probleme in einer angemessenen Zeit erfolgreich lösen und das Projekt zum Erfolg führen. Das Gleiche gilt für andere Sprachen. Sorgfältiges und richtiges Design und Planung ist doch um Größenordnungen wichtiger als unbedingt die Sprache. Für Steueraufgaben mäßiger Komplexität kommt man mit C immer zurecht. In fast zwanzig Jahren brauchte ich nur einmal eine Sortierfunktion. Mir scheint (aus meiner Sicht) es ist also für viele Entwickler eher nur eine esoterische Notwendigkeit. Für Anwendungen mit GUI gelten natürlich andere Betrachtungen und Voraussetzungen und C++ ist dafür wahrscheinlich viel besser geignet. Aber das wird man ja heutzutage kaum auf einem 8-bitter uC machen wollen. Und bei leistungsfähigerer HW. spielt der höhere Resourcenverbrauch sowieso nur eine zweitrangige Rolle. Schönes Wochenende, Gerhard
:
Bearbeitet durch User
Nop schrieb: > Sheeva P. schrieb: >> Aber da Du ja sachliche >> Argumente gefunden haben willst, kannst Du sie doch sicherlich zitieren. > > Es ist doch allgemein bekannt, wenn man nicht nur die belustigenden > Teile von Torvalds' Rants liest, daß die sehr wohl versucht haben, ob > C++ im Kernel sinnvoll ist. Sicher war C++ damals bei weitem nicht da, > wo es heute ist, aber die Grundphilosophie der compiler magic ist nicht > weniger, sondern mehr geworden. Also wieder keine sachlichen Argumente, stattdessen nur das jetzt sattsam bekannte Argumentum ad verecundiam (die Berufung auf Linus als Autorität) sowie ein Argumentum ad populum (etwas sei "allgemein bekannt"). Angeblich soll Linus C++ einmal im Jahre 1992 ausprobiert haben, als alles noch in den Kinderschuhen steckte: Linus, sein Kernel, und auch C++. Auch dazu hat er leider nichts geäußert, was Ähnlichkeit mit einem sachlichen Argument gehabt hätte. >> Frag' Dan, seine Kontaktdaten findest Du dort: [1]. > > Wenn Dan etwas wie den Kernel oder Git vorzuweisen hätte, wüßte man das, Nö. Außerhalb der OpenSource-Welt sind nur sehr wenige Entwickler bekannt geworden. Es gibt viele Softwareprojekte, deren Komplexität und Umfang die von Linux, von Git, und von beiden zusammengenommen weit übersteigen. Aber deren Entwickler kennt dennoch niemand. Und sogar innerhalb der OSS-Welt sind die meisten Entwickler völlig unbekannt. > Eben das ist das Problem: > > http://www.rachelslabnotes.com/2009/10/the-hidden-cost-of-c/ LOL! > Insofern spart C++ da Kosten beim Erstellen, aber sobald der Entwickler > weg ist, schlagen die Folgekosten umso heftiger zu. Und zwar jedesmal, > wenn der Entwickler wechselt. > > Mag für Dich egal sein, wenn Du selbständig ist und daher Deine Produkte > selber betreust. Ach, weißt Du, ich arbeite seit vielen Jahren in kleinen, mittleren, und manchmal auch recht großen Teams, und bisher sind mir die Probleme, deren Vorhandensein Du behauptest, in der Praxis noch nie begegnet. Das kommt vielleicht davon, daß Beispiele wie jenes von Rachel "groby" Blum, die Du oben zitierst, vollkommen konstruiert und irrelevant sind, weil niemand in der Praxis so etwas schreiben würde. (Und wenn das einer meiner Entwickler täte, hätte er spätestens nach dem ersten Code Review einige ausgesprochen unangenehme Gespräche vor sich.) Es ist billig, sich irgendwelchen irrelevanten Quatsch aus den Fingern zu saugen, den niemand in der Realität machen würde, und diesen Quatsch dann als Argument zu mißbrauchen. Das nennt man ein "hypothetisches Argument", das schon daran krankt, daß die Prämisse -- nämlich, daß jemand so etwas schreiben würde -- schlicht nicht zutrifft. In der Praxis ist C++ leichter zu lesen und zu verstehen als die wüsten Orgien von Referenzierung und Dereferenzierung, Casts und Zeigerarithmetik, die ich in C schon gesehen habe -- die allerdings in der Praxis, und nicht nur in der Theorie. >> Also schaut unser Hirni natürlich nach, was da gemacht >> wird -- genau wie bei einem "normalen" Funktionsaufruf auch. > > Siehste, Du nimmst das also nicht als Problem wahr. Deswegen zählst Du > zu genau den Leuten, die ein Torvalds aus seinen Projekten schon dadurch > vergraulen will, daß er sich für C anstatt für C++ entscheidet. Und trotzdem hat er Patches von uns angenommen, ist das nicht lustig? >> Das ist eine sehr kurzsichtige Sichtweise, die alle langfristigen >> Effekte besserer Codeorganisation, Les- und Wiederverwendbarkeit >> ignoriert. > > Als ob das rein durch C++ gegeben wäre - im Gegenteil, weil es noch viel > mehr Möglichkeiten gibt, wie man falsch abbiegen kann. Zwischen "falsch abbiegen können" und "falsch abbiegen" liegen aber immer noch Welten. Und, wie gesagt: man kann in jeder Programmiersprache miesen Code schreiben, da bilden C und C++ keine Ausnahme. >> meiner Erfahrung sind Entwickler und Unternehmen, die sich nicht >> weiterentwickeln und -bilden wollen, ziemlich bald auf dem Abstellgleis >> anzutreffen. > > Wer jedem Hype hinterherrennt, nur weil's neu ist, macht sich auch nicht > besser. Sicher, aber darum geht es ja nicht. C++ ist kein Hype, sondern längst eine etablierte Programmiersprache. Das einzige mir bekannte Umfeld, in dem sich noch Leute um "C vs. C++" kloppen, ist das Mikrocontroller-Umfeld. Und da begegnen einem selten sachliche Argumente, sondern immer wieder dieselben Vorurteile, die entweder noch nie gestimmt haben oder im Laufe der Jahre längst behoben worden sind.
Nop schrieb: > Abgesehen davon sind bei ernsthafteren Projekten keine > Compiler-Optimierungen erlaubt, Hab ich oft genug schon gesehen. Allerdings aus eine anderen Grund. Der Code lief mit Optimierungen nicht mehr richtig und das wurde dann auf den Compiler geschoben. Tatsächlich lag es an nicht wenigen Programmierfehlern. Ich hab oft genug schon den Assembleroutput von Compilern debuggt. Ein einziges mal hab ich tatsächlich einen Fehler gefunden, der sich aber nur in Verbindung mit Assemblercode zeigte (avr-gas). In allen anderen Fällen war der Programmierer schuld. Ich behaupte das in mindestens 99,999% der Fälle, in denen Programme mit Optimierung nicht laufen, die Schuld bei den Programmierern liegt und es gerne auf den Compiler geschoben wird. Keiner ist unfehlbar, jeder macht Fehler beim Programmieren - die Optimierung abzulehnen ist jedoch ein weitaus schlimmerer. Oftmals findet man Fehler erst dadurch, dass der Compiler Code wegoptimiert, weil der Programmierer falschen Code schreibt. Somit steigt auch die Codequalität. Ansonsten funktioniert der Code im schlimmsten Fall mit einer neuen Compilerversion nicht mehr. Gerhard O. schrieb: > Ich finde, soll doch jeder diejenige Werkzeuge verwenden die (für ihn) > zum vernünftigen Erfolg führen. Sehe ich auch so, solange man nicht über Werkzeuge herzieht, die man nicht kennt.
Nop schrieb: > Zumal > ich nicht glaube, daß sich die ST-HAL dank LTO wirklich in direkte > Registerzugriffe übersetzt. Glauben kannst du in der Kirche. Mit der Cube Hal muss man sogar eine Data Synchronisation Barrier zwischen Aktivierung des Taktes und Peripherieinitialisierung einbauen. Ansonsten schlägt diese gerne fehl (siehe auch Errata).
Gerhard O. schrieb: > Ich finde, soll doch jeder diejenige Werkzeuge verwenden die (für ihn) > zum vernünftigen Erfolg führen. Der TO hatte nach einer Empfehlung für ein Werkzeug, genauer: einer Sprache gefragt -- und angelegentlich einige etwas krude Aussagen getätigt. Daraus hat sich dann eine Diskussion entwickelt, in der einige Diskutanten diese Aussagen geradezurücken versucht, und andere jenen widersprochen haben. Kurz gesagt, gibt es hinsichtlich geeigneter Sprachen für μCs mehrere "Fraktionen". Da sind einerseits jene, die von jeher nur mit Assembler arbeiten wollen oder können, andererseits gibt es eine recht starke C- sowie eine etwas weniger starke C++-Fraktion. Bereits zwischen diesen Fraktionen gibt es mehr oder weniger sachliche Diskussionen. Derartige Diskussionen werden aber nicht einfacher dadurch, daß es innerhalb der Fraktionen wiederum unzählige Subfraktionen gibt: manche mit Exoten wie Haskell, Forth, Oberon oder Modula, andere mit Erfahrung in Assembler, C und C++, wieder andere mit Erfahrung in lediglich einer dieser Sprachen, und dann wiederum Leute mit Abneigungen gegen eine der Sprachen. > Es hieß ja vor langer Zeit, C wäre ja nur ein verbesserter Assembler. > Hardware nahe läßt sich Vieles Resourcen effizient erreichen und ist für > knappe uC ideal. Das gilt zum Teil auch für C++, wenn mit Verstand > eingesetzt. Das gilt ganz genau so für C++ wie für C. Beide muß man mit Verstand nutzen, beide haben ihre Fallstricke (think malloc(3) und new) und müssen deswegen auf eng limitierten Umgebungen wie μC immer mit Verstand eingesetzt werden. Mit zunehmender Leistungsfähigkeit des μC und zunehmender Komplexität des Programms können immer mehr Features benutzt werden. > Für Anwendungen mit GUI gelten natürlich andere Betrachtungen und > Voraussetzungen und C++ ist dafür wahrscheinlich viel besser geignet. Das ist der Grund, warum sich OO-Sprachen wie C++, Java und C# in der GUI-Entwicklung durchgesetzt haben. > Aber das wird man ja heutzutage kaum auf einem 8-bitter uC machen > wollen. Und bei leistungsfähigerer HW. spielt der höhere > Resourcenverbrauch sowieso nur eine zweitrangige Rolle. Siehst Du, und da ist es schon wieder, eines dieser Vorurteile. C++ hat überhaupt gar keinen höheren Ressourcenverbrauch als C, wenn man es mit Verstand einsetzt. Richtig ist, daß der Lernaufwand ein wenig höher ist, was sich aber schnell relativiert, wenn man zum Beispiel auch Prüf- oder andere Werkzeuge für den PC schreiben will oder muß. Für jene, die das nicht müssen, bietet ein -- mit Verstand genutztes -- C++ eine bessere Codeorganisation, Typsicherheit, Les-, Wart- und Wiederverwendbarkeit. Zweifellos gibt es ein paar Leute, die wirklich nur die kleinsten aller μC-Programme schreiben und darum auf solche Features verzichten können. Sowas ist auch ganz legitim, sollen diese Leute mit ihrem C oder ihrem Assembler glücklich sein und bleiben. Kein Problem, solange sie keinen Unsinn über andere Sprachen reden. Ich persönlich bin da eher pragmatisch orientiert: auf PCs (und SBCs wie dem RasPi) nutze ich -- je nach Anforderungen, zeitlichen Beschränkungen, Verfügbarkeit von Bibliotheken und Werkzeugen -- wahlweise Python, C++, sowie Java. Auf μCs benutze ich in der Regel C++, meist aber nur wenige Features. Das richtige Werkzeug für meine konkrete Aufgabe zu wählen, funktioniert aber nur dann, wenn ich tatsächlich eine Wahl habe: also mehrere Werkzeuge beherrsche und ihre Stärken und Schwächen kenne.
Sheeva P. schrieb: >> Aber das wird man ja heutzutage kaum auf einem 8-bitter uC machen >> wollen. Und bei leistungsfähigerer HW. spielt der höhere >> Resourcenverbrauch sowieso nur eine zweitrangige Rolle. > Siehst Du, und da ist es schon wieder, eines dieser Vorurteile. C++ hat > überhaupt gar keinen höheren Ressourcenverbrauch als C, wenn man es mit > Verstand einsetzt. Hallo Sheeva, wollte gerade abschalten und konnte aber nicht umhin hier nochmals nachschauen;-) Vielen Dank für Deine Ausführungen. Aber da hatte ich mich wahrscheinlich unklar ausgedrückt. Ich bezog mich in diesem Paragraph nicht auf die Wahl der Sprache sondern lediglich auf die Leistungsfähigkeit der HW und Speicherplatz Ressourcen. Ich wollte wirklich keine Werkzeug Vorurteile aussprechen. Wenn GUI zur Anwendung kommt, verstehe ich diesbezüglich z.B. als Minimum ein HW System auf ARM7TDI/Cortex Basis mit externen großen FLASH Speicher (64MB) und SDRAM (16MB) und richtigen TFT Graphics Controller mit Touchscreen Interface, Ethernet und sonst noch alles Mögliche. Damit läßt sich ein gut funktionierendes System erreichen. Z.B. auf einem ATMEGA2560 war die Leistung eines GUI mit TFT (320x240) schon mehr als gewöhnungsbedürftig. Wir probierten das mal aus und es war (wie erwartet) nicht sehr befriedigend. Es funktionierte zwar; aber kein Vergleich zu den 32-bittern mit viel höherer Leistung. Aber dafür kann der AVR nichts. Für solche Zwecke war er ja nie gedacht. Deshalb finde ich es irgendwie unangebracht auf dem Markt (z.B. Arduino, Adafruit...) solche Bords, TFTs und LIBs anzubieten weil die Voraussetzungen für ein schnelles GUI mit befriedigender Leistung einfach nicht gegeben sind. Da spielt die Wahl der Sprache wenig Rolle. Die HW. Architektur für ein High Performance GUI muß eben aufwendig genug sein um am Ende befriedigende Leistung zu erbringen und die Entwicklung nicht zur Qual werden lassen. Und dazu gehört auch die Wahl der Werkzeuge und Sprachen.
:
Bearbeitet durch User
Sheeva P. schrieb: > C++ ist kein Hype, sondern längst > eine etablierte Programmiersprache. Definitiv nicht bei einfacherern MCs, und das hat die hinreichend bekannten Gründe. Das wird auch so bleiben. Vielleicht kann man es so beschreiben: Komplexe Architekturen verlangen nach komplexen Sprachen, einfache nach einfachen. Leistet eine Hochsprache wie C++ bei datenintensiven Plattformen wie ARM oder gar PC noch einen Beitrag, die Dinge in den Griff zu bekommen ist sie im Umfeld einfacher Controller eher zusätzliche Belastung- mit der großen Gefahr, hier ineffizienten Code zu schreiben. Nicht daß sie zwangsläufig dazu führen müsste, aber sie provoziert ihn, denn da gibt es immer noch den Faktor Mensch, der mit dem Füllhorn sprachlicher Möglichkeiten auch umgehen können muß. Zur perfekten Beherrschung aber ist für C++ immer noch ein längerer Ausbildungsweg nötig als ihn einfachere Sprachen voraussetzen. Schlußendlich bleibt eigentlich nur eines festzustellen: Die Gleichung "richtige Programmiersprache" enthält neben den Möglichkeiten der Sprache und den Erfordernissen des Programms immer auch den Faktor Mensch mit seinen Kenntnissen, Voraussetzungen und Vorlieben.
Sheeva P. schrieb: > Kurz gesagt, gibt es hinsichtlich geeigneter Sprachen für μCs mehrere > "Fraktionen". Da sind einerseits jene, die von jeher nur mit Assembler > arbeiten wollen oder können, andererseits gibt es eine recht starke C- > sowie eine etwas weniger starke C++-Fraktion. Bereits zwischen diesen > Fraktionen gibt es mehr oder weniger sachliche Diskussionen. Derartige > Diskussionen werden aber nicht einfacher dadurch, daß es innerhalb der > Fraktionen wiederum unzählige Subfraktionen gibt: manche mit Exoten wie > Haskell, Forth, Oberon oder Modula, andere mit Erfahrung in Assembler, C > und C++, wieder andere mit Erfahrung in lediglich einer dieser Sprachen, > und dann wiederum Leute mit Abneigungen gegen eine der Sprachen. Ich habe eher den Eindruck, daß es innerhalb von Firmen oft schwer ist über den Tellerrand zu schauen um Vergleiche mit fortschrittlichen Werkzeugen zu ermöglichen. Da muß man als Entwickler oft Eigeninitiative ergreifen um sich ein Bild vom Fortschritt machen zu können und eigene erste Erfahrungen sammeln zu können. Meistens ist es so, daß schon vorhandene firmeneigene Werkzeuge verwendet werden (müssen oder) sollen und schon vorhandene Bibliotheken und vorhandener Code wiederverwendet werden muß. Viele Projekte sind Weiterentwicklung schon existierender Gerätschaften oder Produkte und da will die GL auch nicht ohne zwingenden Grund Jahrzehnte investierte Arbeit wegschmeißen. Oft kommen dann auch noch erschwerend die Kosten von Neuzulassungen dazu. Um in einem solchen Umfeld neue Tools und neue Wege zu verlangen und beschreiten kann schwierig sein. Aber das kennt ihr ja alle. Dann ist oft keine Zeit für Training und Lernen. Meist erwartet die GL, daß man gleich produktiv sein muß. Da ist dann kein Wunder wenn der "Bauer nichts frißt, was nicht auf seinem Feld gewachsen ist" und man weiterhin althergebrachte Wege wie von jeher beschreitet. Dann bleibt die Entwicklung (leider) stehen und das Wissen stagniert und die MA atmen bald den Staub der Einsichtigeren (oder Glücklicheren) ein, die mit Elan an solchen Firmen vorbei flitzen. Leider kann sich nicht jeder Entwickler aussuchen wo er lieber sein möchte.
Atlas schrieb: > Leistet eine Hochsprache wie C++ bei > datenintensiven Plattformen wie ARM oder gar PC noch einen Beitrag, die > Dinge in den Griff zu bekommen ist sie im Umfeld einfacher Controller > eher zusätzliche Belastung- Genau. Ich möchte meine klein aber fein bekannte Hardware direkt, klar und verständlich ansprechen und nicht in einem abstrakten Wust mit 3 Mal um die Ecke denken vernebeln lassen.
Ich sehe das 'andersrum': weil ich lieber mit C++ arbeite und die Vorzüge nutzen möchte nehme ich passende Controller dazu (Hobby, keine HW/SW Zwänge). Und das geht bei Cortex-M0 los die mechanisch nicht größer als ATtiny sind aber viel mehr Dampf haben. Und nach oben hin geht es mit gleichen oder ähnlichen Werkzeugen zu Devices mit Ethernet und schnellen Grafikkontrollern.
Hallo Sheeva,
> Auf μCs benutze ich in der Regel C++, meist aber nur wenige Features.
Welche sind das? Das würde mich wirklich mal interessieren.
rhf
Roland F. schrieb: > Hallo Sheeva, > >> Auf μCs benutze ich in der Regel C++, meist aber nur wenige Features. > > Welche sind das? Das würde mich wirklich mal interessieren. Ich denke, dass Sheeva das genauso sieht wie ich: Nicht auf µC verwenden: - RTTI und dyn. Polymorphie - Exceptions - Heap-Allokation Sehr gut zu verwenden: grundsätzlich alles, was Compiletime-Berechnungen zur Folge hat. - TMP: haupsächlich als template-Metafunktionen - variadische templates und fold-expressions - constexpr, constexpr-functions, constexpr-lambdas und IIFE, constexpr-if - statische Polymorphie - constraints und concepts Die Basis dafür ist ein "reiches Typsystem" (was man sich in seiner Domäne schafft, etwa wie die oben schon mal angesprochenen SI-Einheiten), denn jede Information, die man in die DT codiert, ist eine Information weniger, die man zur Laufzeit auswerten muss (manchem mag es merkwürdig erscheinen, das man bspw. ganzzahlige Informationen auch als DT (etwa wie std::integral_constant, std::false_type, std::true_type) darstellen kann). Und auch damit zur Compilezeit rechnen kann, so dass das Ergebnis eine Konstante zur Laufzeit ist. Das erscheint vielen wahrscheinlich befremdlich, aber die template-engine ist eben turing-complete, wobei ich hier nicht zur mit Werten zur Compilezeit rechnen kann, sondern ich kann mit Typ-Information rechnen! Nochmal: Typinformation kostet keine Laufzeit, eher im Gegenteil. Wenn ich die Kommentare auch in diesem Thread lese, dann haben (fast) alle bei C++ Laufzeit-Polymorphie im Sinn. Und das ist (s.o.) ein Feature dieser multiparadigmen Sprache, was auf µC aus gutem Grunde nicht zum Einsatz kommt bzw. sehr mit Bedacht eingesetzt werden muss. Wer aus diesem, etwa durch Java oder C# geprägtem Blickwinkel, auf C++ schaut, sieht die vielfältigen Möglichkeiten gar nicht. Aber man sollte auch die "Kleinigkeiten" wie Funktionsüberladung, RAII, ranged-based-loops, scoped enums, structured bindings, UDL, Op-Overload, statische generische Container, unified-initialization, ... nicht vergessen. (Jetzt ahbe ich bestimmt ein paar auch von mir sehr oft genutzte goodies vergessen).
:
Bearbeitet durch User
Wilhelm M. schrieb: > Nicht auf µC verwenden: > > - RTTI und dyn. Polymorphie > - Exceptions > - Heap-Allokation Und auf größeren µCs kann man sogar diese verwenden. Vor einem Jahr habe ich http://www.partow.net/programming/exprtk/index.html auf einem STM32F4 eingesetzt. Das kostete zwar 1 MB an Flash, aber die Bibliothek lief einwandfrei und vor allem wahnsinnig schnell (was auch wichtig war). Sie nutzt übrigens alle oben aufgeführten Punkte.
Johannes S. schrieb: > weil ich lieber mit C++ arbeite und die > Vorzüge nutzen möchte nehme ich passende Controller dazu ... > Und das geht bei Cortex-M0 los ... viel mehr Dampf haben So kann man natürlich auch ausdrücken, daß C++ seinen Hardware-Tribut einfordert. Sheeva P. schrieb: > Zweifellos gibt es ein paar Leute, die wirklich nur die kleinsten aller > μC-Programme schreiben und darum auf solche Features verzichten können. Also ich fülle meine AVR-Flashspeicher in C oder purem Assembler meist gut aus, da werden es schon nicht die "kleinsten aller μC-Programme" sein. Auf welche glorreichen, unverzichtbaren C++ Features ich da bislang verzichten musste (außer jenes natürlich, dafür erst dicke Lehrbücher pauken zu müssen) ist mir auch nicht ganz klar... So richtig austoben können sich Fans hochabstrakter Konstruktion doch damit nur, wenn viel Speicher nun wirklich keine Rolle mehr spielt. Weder bin ich aber das eine noch steige ich deshalb um auf andere, leistungsfähigere MCs. Die wertvolle Zeit ist immer noch besser in die eigentlichen Projekte als in fortlaufend neue Controller, Sprachen und Arbeitsmittel investiert. Aus meiner bescheidenen Hobby-Sicht.
FinFet schrieb: > Also ich fülle meine AVR-Flashspeicher in C oder purem Assembler meist > gut aus, da werden es schon nicht die "kleinsten aller μC-Programme" > sein. Auf welche glorreichen, unverzichtbaren C++ Features ich da > bislang verzichten musste (außer jenes natürlich, dafür erst dicke > Lehrbücher pauken zu müssen) ist mir auch nicht ganz klar... Dann ist doch alles ok. Dann bleib dabei! > So richtig > austoben können sich Fans hochabstrakter Konstruktion doch damit nur, > wenn viel Speicher nun wirklich keine Rolle mehr spielt. Eben nicht! Wieder dieses Vorurteil ... Was ich oben als gut zu benutzende Features aufgelistet habe, "kostet" nichts im direkten Vergleich zu C, aber es macht Programme lesbarer, wartbarer, weniger fehleranfälliger, robuster, ...
FinFet schrieb: > Also ich fülle meine AVR-Flashspeicher in C oder purem Assembler meist > gut aus, da werden es schon nicht die "kleinsten aller μC-Programme" > sein. Das ist schön für dich und legitim. FinFet schrieb: > Auf welche glorreichen, unverzichtbaren C++ Features ich da > bislang verzichten musste (außer jenes natürlich, dafür erst dicke > Lehrbücher pauken zu müssen) ist mir auch nicht ganz klar... Das ist vermutlich das Problem bei dir... FinFet schrieb: > So richtig > austoben können sich Fans hochabstrakter Konstruktion doch damit nur, > wenn viel Speicher nun wirklich keine Rolle mehr spielt. In C++? Nein. avr schrieb: > Hab ich oft genug schon gesehen. Allerdings aus eine anderen Grund. Der > Code lief mit Optimierungen nicht mehr richtig und das wurde dann auf > den Compiler geschoben. Tatsächlich lag es an nicht wenigen > Programmierfehlern. Oh ja, hatte es mal mit einem Kollegen zu tun, der aus der Flugzeugsoftware-Branche kam. Ich durfte eine Firmware für einen Prototypen von ihm zum Laufen bringen. Optimierungen waren bei ihm total verpönt, macht nur Probleme. Und was war? Sobald man die Optimierung anschaltete (da reichte schon -O1), machte die Firmware irgendwas undefiniertes. Der Grund war, dass Variablen die zwischen Interrupts und Mainthread benutzt wurden, keinen Zugriffsmodifier "volatile" besaßen. Der Typ hatte schlichtweg keine Ahnung davon, aber Schuld sind natürlich die Optimierungen gewesen. Würde mich nicht wundern, wenn seine ehemaligen Kollegen auch so Knalltüten sind.
>> ISBN 978-3-642-83565-0 >> T:"Programming in Modula-2" >> A:"N. Wirth" > > Ich habe dieses Buch nicht und kann die entsprechende Seite auch in > books.google.com nicht finden. Vermutlich sieht die Syntaxbeschreibung > in etwa so aus: > > https://www.modula2.org/tutor/syntax.php > > Weil das aber in lesbarer Schriftgröße kaum auf eine A4-Seite passt, > hätte mich interessiert, wie es im Original aussieht. :-). 1 A4 Blatt ~ 2 A4 Seiten ok? Hier noch die letzte der PIM Varianten, halt noch mit Prosa dazwischen: * <http://freepages.modula2.org/report4/modula-2.html>
1 | $ curl -s http://freepages.modula2.org/report4/modula-2.html ¦ grep -oc '$ .*$' |
2 | 114 |
3 | $ # die erste Zeile ist zuviel, also 113 oder noch weniger |
Nach durchschütteln von google doch noch ein "Original", S.42+43 = 2x A5 Seiten (also gar nur 1 A5 Blatt!) * <http://eah-jena.de/~kleine/history/languages/Wirth-Modula2.pdf> Die Unterschiede zu der von dir verlinkten ISO Varianten fallen bezüglich (un-)Kompaktheit auf z.B. bei fieldlist oder dem CASE Statement. Da scheint bei EBNF auch noch ordentlich Luft für "künstlerische Freiheiten" zu sein... Mit der ISO Variante hatte ich selbst noch nicht das vergnügen. An einem ehem. Arbeitsplatz konnte ich aber ~10 J BE sammeln mit "Tailor M2": R&D bei Hersteller von VCS f. ATC, also Embedded (68k & PPC), RT Sprachkommunikation weil massig PCM30 basiert. Rund 200 operative Systeme installiert vom Lappland bis Südafrika / von Portugal bis China (inkl. ESA + ein paar Sonderanwendungen ausserhalb ATC). Definitiv reale Industrie, nicht Akademie.
Hier ist ja mal wieder eine echte C vs C++ Duskussion im Gange. :) Dann will ich mal meine Ansicht zum Besten geben. Ich war sehr lange der Meinung, man müsse kleine 8-Biter mit C programmieren, da C++ der totale Overkill dafür ist. Mittlerweile sehe ich das etwas anders. Man kann C++ sehr wohl gewinnbringend auf kleinen µC einsetzen. Ein guter Proof of Concet ist meiner Meinung nach "Arduino" [Bitte nicht schlagen :D]. Da gehört zwar noch Ordnung rein und ein Teil sollte etwas weniger verschwenderisch umgestzt sein, aber im großen und Ganzen zeigt es, dass man mit C++ durchaus Code produzieren kann, der sich sehr einfach verstehen/verwenden lässt. Ehrlich gesagt nutze ich das sogar privat für meine Bastelprojekte, da man UART/Zeitmessung/u.a. einfach schon geschenkt bekommt. Ich habe dafür den avr-arduino-core geforkt und da dann alles was ich so brauchte drüber gesetzt. Das Letzte was ich dafür (aus Spaß an der Freude) gemacht hab sind I2C-Treiber für ein paar I2C-ICs die ich hier so rumliegen hatte. Das sind alles Klassen, die im Konstruktor eine Referenz auf einen abstrakten I2C-Bus erwartet haben. Damit konnte ich sehr gut verschiedene I2C-Treiber (HW/SW) reingeben und auch einen I2C-MUX abbilden. Die Treiber ließen sich perfekt Unittesten, indem man einfach einen I2C-Bus-Mock(gmock) beim Instanziieren reingegeben hat. Angelegt wurden die Objekte für den AVR statisch. Ich glaube nicht, dass das am Ende so viel mehr Speicher gebraucht hat, als eine äquivalente Lösung in C. Das Vorgehen mag vielleicht für einige Mitstreiter so wirken, als würde man so mit Kanonen auf Spatzen schießen, aber für mich zählen hier mittlerweile ganz klar die Lesbarkeit und die Wartbarkeit. Ich erreiche beides durch die Verwendung von C++ leichter als mit der Sprache C. Von mir für den AVR-Code genutzte Features aus C++11 (Reihenfolge hat keine Bedeutung): - Polymorphie (für Interfaces -> ist gar nicht so teuer wie man denkt, sollte aber trotzdem sparsam eingesetzt werden) - Enum-Klassen (die Namensraumverschmutzung in C ist doch grausig oder?) - Überladen (eher für Methoden, weniger für Operatoren) - Namespaces (das schafft richtig Ordnung) - References (viel schöner als Pointer) - Lambda-Ausdrücke - Default-Parameter - Templates (damit bin ich aber sehr sparsam, da es die Lesbarkeit rapide sinken lässt) - ... mehr fällt mir jetzt nicht ein Es muss natürlich jeder für sich entschieden, was er hernimmt, aber ich für meinen Teil werde nicht mehr auf C++ für die AVR verzichten. Edit: Ich nutze C++ seit nun mehr als 4 Jahren beruflich im (Fast-)Embedded-Bereich (Cortex-A8 mit vielen MB Flash und RAM und OS ist ja nicht wirklich embedded) Grüße Oliver
:
Bearbeitet durch User
Gerhard O. schrieb: > Ich bezog mich in diesem Paragraph nicht auf die Wahl der Sprache sondern > lediglich auf die Leistungsfähigkeit der HW und Speicherplatz Ressourcen. Ja, ich auch. Mit Verstand eingesetzt, kostet C++ im Vergleich zu C: nichts. C++ verbraucht nicht mehr Hardwareressourcen und keinen Speicherplatz, der Mehrverbrauch gegenüber C an CPU-Takten, Flash- oder RAM-Speicher ist gleich null. Genau das ist es, was ich meine: der Glaube, C++ würde mehr CPU-Takte, mehr RAM oder mehr Flash verbrauchen, ist falsch -- und ein Vorurteil.
Atlas schrieb: > Definitiv nicht bei einfacherern MCs, und das hat die hinreichend > bekannten Gründe. Du meinst: die hinreichend bekannten Vorurteile. > Das wird auch so bleiben. Das glaube ich nicht, aber wir werden sehen. Prognosen sind bekanntlich schwierig, vor allem, wenn sie die Zukunft betreffen. > Vielleicht kann man es so beschreiben: Komplexe Architekturen verlangen > nach komplexen Sprachen, einfache nach einfachen. Diesen Status hatte die Diskussion eigentlich schon überwunden.
Roland F. schrieb: >> Auf μCs benutze ich in der Regel C++, meist aber nur wenige Features. > > Welche sind das? Das würde mich wirklich mal interessieren. Templates, Vererbung, Referenzen, Scoped Enums, um ein paar Beispiele zu nennen. Selten bis gar nicht: Polymorphie, dynamische Speicherverwaltung, dynamisches Binden zu Laufzeit, Mehrfachvererbung.
FinFet schrieb: > Also ich fülle meine AVR-Flashspeicher in C oder purem Assembler meist > gut aus, da werden es schon nicht die "kleinsten aller μC-Programme" > sein. Auf welche glorreichen, unverzichtbaren C++ Features ich da > bislang verzichten musste (außer jenes natürlich, dafür erst dicke > Lehrbücher pauken zu müssen) ist mir auch nicht ganz klar... Also: Du kennst D++ nicht und willst es auch nicht lernen, bist Dir aber schon ganz sicher, daß C++ einen "Hardware-Tribut" einfordert.
Sheeva P. schrieb: > Atlas schrieb: >> Definitiv nicht bei einfacherern MCs, und das hat die hinreichend >> bekannten Gründe. > > Du meinst: die hinreichend bekannten Vorurteile. Nö. Gründe. Daß zumindest bis Stand heute bei MCs immer noch "niedere" Sprachen die Oberhand haben räumst Du ja mit >> Das wird auch so bleiben. > > Das glaube ich nicht, aber wir werden sehen selber ein. Nun gibt es aber sowohl MCs als auch C++ nicht erst seit gestern... Am PC hingegen hat es sich aus ebenso guten Gründen behauptet. Sheeva P. schrieb: > der > Glaube, C++ würde mehr CPU-Takte, mehr RAM oder mehr Flash verbrauchen, > ist falsch -- und ein Vorurteil Nö. Weil Menschen damit programmieren. Je komplexer das Werkzeug desto schwieriger der richtige Einsatz. Das übersiehst Du mit einer vehementen Konstanz die fast schon beängstigend ist :)
Atlas schrieb: > Sheeva P. schrieb: >> der >> Glaube, C++ würde mehr CPU-Takte, mehr RAM oder mehr Flash verbrauchen, >> ist falsch -- und ein Vorurteil > > Nö. Weil Menschen damit programmieren. Je komplexer das Werkzeug desto > schwieriger der richtige Einsatz. Das übersiehst Du mit einer > vehementen Konstanz die fast schon beängstigend ist :) Naja, wenn Du nur einen Faustkeil zur Verfügung hast, brauchst viele Arbeitsschritte, machst viele Fehler und verbrauchst u.U. mehr Material, um ein Handy zu bauen, als wenn Du die richtigen Maschinen verwendest.
Wilhelm M. schrieb: > Naja, wenn Du nur einen Faustkeil zur Verfügung hast, brauchst viele > Arbeitsschritte, machst viele Fehler und verbrauchst u.U. mehr Material, > um ein Handy zu bauen, als wenn Du die richtigen Maschinen verwendest. Und Du glaubst wirklich, Asm+C/C++ vs. Faustkeil/richtige Maschine wär ein passender Vergleich? Warum hat (Misra-)C eine jahrzehntelang unangefochtene Stellung bei den MCs? Die Antwort auf diese Frage würde glaube ich weiterführen!
Atlas schrieb: > Wilhelm M. schrieb: >> Naja, wenn Du nur einen Faustkeil zur Verfügung hast, brauchst viele >> Arbeitsschritte, machst viele Fehler und verbrauchst u.U. mehr Material, >> um ein Handy zu bauen, als wenn Du die richtigen Maschinen verwendest. > > Und Du glaubst wirklich, Asm+C/C++ vs. Faustkeil/richtige Maschine wär > ein passender Vergleich? Warum hat (Misra-)C eine jahrzehntelang > unangefochtene Stellung bei den MCs? Die Antwort auf diese Frage würde > glaube ich weiterführen! Misra-C gibt keine Antwort auf die Frage C vs C++. Misra-C++ gibt auch keine Antwort auf die Frage C++ vc C. Diese Guidelines betrachten jeweils nur die Zielsprache.
Wilhelm M. schrieb: > Atlas schrieb: > >> Sheeva P. schrieb: >>> der >>> Glaube, C++ würde mehr CPU-Takte, mehr RAM oder mehr Flash verbrauchen, >>> ist falsch -- und ein Vorurteil >> >> Nö. Weil Menschen damit programmieren. Je komplexer das Werkzeug desto >> schwieriger der richtige Einsatz. Das übersiehst Du mit einer >> vehementen Konstanz die fast schon beängstigend ist :) > > Naja, wenn Du nur einen Faustkeil zur Verfügung hast, brauchst viele > Arbeitsschritte, machst viele Fehler und verbrauchst u.U. mehr Material, > um ein Handy zu bauen, als wenn Du die richtigen Maschinen verwendest. Oder auch: wer bisher nur einen Faustkeil hatte, wird den Vorteil eines Hammers nicht verstehen, wenn er ihn identisch einsetzt. Er wird sich dann über den störenden Holzstock ärgern. Eigentlich darf's aber jeder machen, wie er's will. (Sie auch) Das gilt für Assembler-Freunde, C-Liebhaber, aber das darf dann bitte auch für die gelten, die lieber C++ benutzen.
Wilhelm M. schrieb: > Misra-C gibt keine Antwort auf die Frage C vs C++. Misra-C und nicht etwa Misra-C++ steht hier in erster Linie für den Standard automobiler Steuergeräte-Software. Deren MC-Bedarf ist wie man weiß nicht ganz unwesentlich. Carl D. schrieb: > Eigentlich darf's aber jeder machen, wie er's will. Das mag ja als salomonisches Urteil durchgehen gibt aber letztlich keine Hilfestellung zum Thema. Den Gläubigen des no-limit abstrakten C++ Himmels auf MCs möchte ich noch zurufen: Manchmal ist weniger mehr, man kann alles auch übertreiben!
Atlas schrieb: > Misra-C und nicht etwa Misra-C++ steht hier in erster Linie für den > Standard automobiler Steuergeräte-Software. Dass es aber mittlerweile ein Misra-C++ überhaupt gibt, zeigt, dass dafür offensichtlich durchaus Bedarf war.
@Atlas Bevor das hier mit dir so weiter geht, würde mich zuerst interessieren, wie gut du überhaupt C++ kennst. Aus deinen Beiträgen heraus lese ich eher, dass du damit nicht wirklich zurecht kommst. Dass C++ nur langsam in der Embedded-Welt ankommt, hängt mMn eher damit zusammen, dass die C++ Compiler, verglichen mit den C-Compilern, eher jung sind. Bis sich das dann in einer schon älteren Firma durchsetzt, dauert das eben etwas. Ich habe das Gefühl, dass tendenziell in kleineren Firmen eher C++ programmiert wird. Wahrscheinlich, weil es in großen Firmen häufig zu viele Personen gibt, die sich dagegen sträuben - mit dem unausgesprochenen Hauptargument, dass sie die Sprache, so hart es klingt, einfach nicht beherschen. Natürlich kann es sinnvoll sein, kleine Projekte in C durchzuführen, weil man weniger qualifizierte Arbeitskräfte einsetzen kann. Wenn man allerdings schon eine entsprechende Codebasis durch andere Projekte in C++ hat, dann zieht das auch nicht mehr. Mit Klassen lässt sich Peripherie wunderbar abstrahieren, und das ohne Overhead, vorausgesetzt man macht es richtig (nicht wie bei Arduino).
Beitrag #5039410 wurde von einem Moderator gelöscht.
AVRler schrieb im Beitrag #5039410: > avr schrieb: >> mit dem unausgesprochenen Hauptargument, dass sie die Sprache, so hart >> es klingt, einfach nicht beherschen > > Weil die Sprache eben doch lernintensiver ist? Selbstverständlich! > Weil viele Entwickler darin für ihre Arbeit keinen Vorteil sehen? Das mag sein - geschieht m.E. aber einfach aus Unkenntnis bzw. dem mangelnden Willen oder der mangelnden Zeit, sich da einzuarbeiten (s. Posts weiter oben). > avr schrieb: >> Mit Klassen lässt sich >> Peripherie wunderbar abstrahieren, und das ohne Overhead, > > Das ist doch ein Märchen. Eben nicht (s.o.: Unkenntnis).
AVRler schrieb im Beitrag #5039410: > Das ist doch ein Märchen. Die periphere Hardware ist dazu viel zu > unterschiedlich. Davon abgesehen benötigt die einfache Peripherie eines > AVRs keine solchen Kopfstände. Naja, wenn ich auf jeder Plattform schon mal das gleiche Interface zu GPIOs und Timern hätte, wäre doch schon viel gewonnen. Ich denke, soetwas kann sehr gut funktionieren, wenn ich meine Bedürfnisse an die Hardware möglichst konkret definieren kann. Wenn ich also eine effektive PWM haben möchte, dann müsste ich das meiner Library so mitteilen. Wenn die Plattform dann peripherals für PWM hat, dann wird das direkt darauf abgebildet. Wenn nicht, wird das halt mit einem Timer umgesetzt. Soetwas kann man mit C++ mit Zero-Overhead Abstraction machen, das ist aber viel Arbeit. Und nein, sagt nicht wieder, dass es nicht geht, wenn ihr C++ nicht kennt.
Hi! Darf ich auch mal? (Öl ins Feuer gießen?) Ich bin nicht nur Arduino Fan, sondern auch noch OOP Fan obendrauf. Damit ist schon mal ganz klar, welche, c oder C++, ich bevorzuge. Davon ab, sind beide Turing vollständig. Also in letzter Instanz gleichwertig. Es ist also eher ein Geschmacksfrage. Und das ist dann der Nährboden für Grabenkriege. In der beruflichen Praxis stellt sich die Frage nur selten. Ein Hobby Programmierer mag sich daran aufgeilen, aber in der Firma/Team wird meist die Firmenlinie verfolgt. Ohne Not davon abweichen? Nö! Mit Recht!
Beitrag #5039493 wurde von einem Moderator gelöscht.
Beitrag #5039537 wurde von einem Moderator gelöscht.
Arduino F. schrieb: > aber in der Firma/Team wird meist die Firmenlinie verfolgt Die muss aber auch mal jemand festlegen. Gelegentlich dürfte sie sich auch ändern, ansonsten würden wohl heute einige große Firmen noch immer alles in FORTRAN programmieren. :) Wie oben schon festgestellt worden ist: in kleinen Firmen dürften solche Änderungen weniger „politischen Wirbel“ verursachen als in großen. Da macht man's einfach, wenn man sich Vorteile davon verspricht.
Beitrag #5039546 wurde von einem Moderator gelöscht.
Beitrag #5039549 wurde von einem Moderator gelöscht.
Beitrag #5039554 wurde von einem Moderator gelöscht.
Beitrag #5039559 wurde von einem Moderator gelöscht.
[ot] Jörg W. schrieb: > Die muss aber auch mal jemand festlegen. Hier mal was zum Thema: "Konservativ" vs." jeden Scheiß mit machen" https://www.youtube.com/watch?v=VdTXdGf4WQQ [/ot]
Beitrag #5039563 wurde von einem Moderator gelöscht.
Beitrag #5039567 wurde von einem Moderator gelöscht.
Beitrag #5039570 wurde von einem Moderator gelöscht.
Beitrag #5039575 wurde von einem Moderator gelöscht.
Beitrag #5039578 wurde von einem Moderator gelöscht.
Beitrag #5039580 wurde von einem Moderator gelöscht.
Beitrag #5039589 wurde von einem Moderator gelöscht.
Beitrag #5039592 wurde von einem Moderator gelöscht.
Beitrag #5039595 wurde von einem Moderator gelöscht.
Beitrag #5039597 wurde von einem Moderator gelöscht.
Beitrag #5039615 wurde von einem Moderator gelöscht.
Beitrag #5039616 wurde von einem Moderator gelöscht.
Beitrag #5039619 wurde von einem Moderator gelöscht.
Beitrag #5039622 wurde von einem Moderator gelöscht.
Beitrag #5039625 wurde von einem Moderator gelöscht.
Beitrag #5039628 wurde von einem Moderator gelöscht.
Beitrag #5039632 wurde von einem Moderator gelöscht.
Beitrag #5039633 wurde von einem Moderator gelöscht.
Beitrag #5039634 wurde von einem Moderator gelöscht.
Beitrag #5039639 wurde von einem Moderator gelöscht.
Beitrag #5039643 wurde von einem Moderator gelöscht.
Beitrag #5039644 wurde von einem Moderator gelöscht.
Beitrag #5039655 wurde von einem Moderator gelöscht.
Beitrag #5039658 wurde von einem Moderator gelöscht.
Beitrag #5039668 wurde von einem Moderator gelöscht.
Karl Käfer schrieb: > Da gibt sich aber jemand Mühe, die Diskussion zu stören. ;-) Wie "stören"? Das sieht hier aus wie das Internet nach dem Netzwerkdurchdringungsgesetz ... :-D
Torsten R. schrieb: > Naja, wenn ich auf jeder Plattform schon mal das gleiche Interface zu > GPIOs und Timern hätte, wäre doch schon viel gewonnen. Ach wo. Gleiche Interfaces sind genau dort von Vorteil, wo man es mit immer wieder gleichartigen Datenströmen zu tun hat, also serielle Interfaces aller Art, SDIO, Grafik-Aufbau in einen Bildspeicher für Display-Aufgaben und dergleichen. Aber schon bei den Timern und noch viel mehr bei den schieren GPIO's hört das komplett auf. Das, was dort stattfindet, ist eigentlich immer derart projektabhängig, daß es absolut kontraproduktiv wäre, dort deinen Gedanken in die Tat umzusetzen. Stattdessen braucht es Treiber, die das jeweilige Problem direkt in eine höhere Ebene umsetzen. Also mal ganz vulgär: nicht "SetzePin(Port,Nummer,Zustand);" sondern "SchalteMotorEin();" Kurzum, der Versuch, auf niedrigster Ebene zu vereinheitlichen, ist unproduktiv. Sowas muß man auf einer angemessenen höheren Ebene machen. W.S.
Torsten R. schrieb: > Naja, wenn ich auf jeder Plattform schon mal das gleiche Interface zu > GPIOs und Timern hätte, wäre doch schon viel gewonnen. STs HAL ist ein Versuch in diese Richtung, zumindest auf STM32. Das reale Ergebnis ist dann, daß man erstens das Datenblatt immer noch lesen muß, um zu verstehen, welche Optionen man genau hat, und sich zweitens auch noch mit der HAL rumschlagen muß. Nicht nur, wie man das benutzen soll, sondern schlimmer noch, wenn man das dann auch noch debuggen muß. Und wehe, man will das dann auch noch plattformübergreifend erweitern. Das wird dann in der Praxis schnell fragmentieren, weil man immer irgendwelche Sachen hat, die mit der Architektur so genau aber gerade nicht gehen. Das erreicht den Punkt, an dem man das wegwerfen kann und schneller mit ein paar Registerzugriffen am Ziel ist. Die Kehrseite von Abstraktion ist Obfuscation. Mir scheint eh, daß es da grundlegend unterschiedliche Denkansätze gibt. Der eine sagt, je mehr Abstraktion, desto besser, und möchte idealerweise reine Mathematik machen. Die grundsätzliche Denkweise ist abstrakt und wird bei Bedarf konkretisiert. Scheint mir typisch für Informatiker zu sein. Der andere möchte das Modell so einfach wie möglich halten, so daß es gerade noch den vorliegenden Fall ausreichend genau annähert. Die grundsätzliche Denkweise ist konkret, und die Modellierung ist nicht Abstraktion, sondern Vereinfachung. Typisch für Ingenieure. Und dann gibt's noch die Physiker, die in jeder Sprache Fortran schreiben.
Beitrag #5039777 wurde von einem Moderator gelöscht.
avr schrieb: > Dass C++ nur langsam in der Embedded-Welt ankommt, hängt mMn eher damit > zusammen, dass die C++ Compiler, verglichen mit den C-Compilern, eher > jung sind. Bis sich das dann in einer schon älteren Firma durchsetzt, > dauert das eben etwas. Ich habe das Gefühl, dass tendenziell in > kleineren Firmen eher C++ programmiert wird. Wahrscheinlich, weil es in > großen Firmen häufig zu viele Personen gibt, die sich dagegen sträuben - > mit dem unausgesprochenen Hauptargument, dass sie die Sprache, so hart > es klingt, einfach nicht beherschen. Na, wer würde schon zu seinem Chef so etwas sagen wie "jetzt nochmal nicht nur eine ganz neue Sprache, sondern sogar ein ganz neues Paradigma lernen, och nö, lieber nicht". Also mein Vorgesetzer würde mich dann nicht ganz zu Unrecht fragen, ob ich wohl noch alle Tässchen im Schränkchen habe. Deswegen wird dann lieber ausgewichen auf "ach nö, Chef, das kostet enorme Ressourcen, dafür brauchen wir größere und teurere Controller und müßten außerdem unsere ganze bewährte Codebasis umbauen". Im Zweifelsfall kann man sogar schnell ein Beispielchen mit Exceptions, dynamischer Polymorphie und ähnlichen Schmankerln bauen, und seine Aussagen damit "beweisen". Was höre ich da, das klänge jetzt arg konstruiert? Ja, ist es, aber leider habe ich solche Vermeidungs- und Verweigerungsstrategien schon erlebt, bei Kollege und auch bei Vorgesetzten. "Das hamwer immer schon so jemacht" ist doch immer wieder ein starkes Argument.
Beitrag #5039831 wurde von einem Moderator gelöscht.
Nop schrieb: > Torsten R. schrieb: > >> Naja, wenn ich auf jeder Plattform schon mal das gleiche Interface zu >> GPIOs und Timern hätte, wäre doch schon viel gewonnen. > > STs HAL ist ein Versuch in diese Richtung, zumindest auf STM32. Das > reale Ergebnis ist dann, daß man erstens das Datenblatt immer noch lesen > muß, um zu verstehen, welche Optionen man genau hat, und sich zweitens > auch noch mit der HAL rumschlagen muß. Nicht nur, wie man das benutzen > soll, sondern schlimmer noch, wenn man das dann auch noch debuggen muß. > > Und wehe, man will das dann auch noch plattformübergreifend erweitern. > Das wird dann in der Praxis schnell fragmentieren, weil man immer > irgendwelche Sachen hat, die mit der Architektur so genau aber gerade > nicht gehen. > > Das erreicht den Punkt, an dem man das wegwerfen kann und schneller mit > ein paar Registerzugriffen am Ziel ist. > > Die Kehrseite von Abstraktion ist Obfuscation. Mir scheint eh, daß es da > grundlegend unterschiedliche Denkansätze gibt. Eigentlich ist kein einziger Chiphersteller daran interessiert vernünftige Bibliotheken anzubieten. Bibliotheken bringen kein Geld und verkaufen keine Hardware. Umso flexibler so eine Bibliothek wäre, umso einfacher wäre ein Port zu einem Fremdprozessor. Eine quasi platformübergreifende Lösung entspräche einem Supergau, da man plötzlich an Konkurrenten, die 0.0001c billiger verkaufen können bereits Kunden verliert... Es ist ja nicht so als wäre ARM nicht bemüht dem entgegenzuwirken. Man versucht mit Dingen wie CMSIS und mbed zu kontern wo es nur geht. Es gibt das SVD Format zur Hardware Beschreibung und sogar Code-Gen Tools für zig-tausende Zeilen lange Header. Die Realität sieht dann so aus, dass etwa ST nicht einmal innerhalb von winzigen Prozessorfamilien (z.B. L4) jene SVD Files und Header konstant hält. Da wird gepfutscht und gepatzt wo es nur geht, mit Sicherheit mangels Interesse und vielleicht sogar aus schlichtem Kalkül. Obwohl mbed zugegebenermaßen eher die IoT Seite anspricht und nicht die "Hardcore"-Embedded Seite, so ist alles über dem setzen eines GPIO Pins ein Krampf... da bekommt man dann ungefähr ein Gefühl dafür, wie ernst es Chiphersteller mit Software-Unterstützung sehn.
Kenuino F. schrieb: > Hi! > > Darf ich auch mal? > (Öl ins Feuer gießen?) <cite> : Everybody I know, whether it’s personal or corporate, selects a subset and these subsets are different. So it’s not a good language to transport an algorithm—to say, “I wrote it; here, take it.” It’s way too big, way too complex. : – Ken Thompson, interviewed about C++ for the book Peter Seibel, Coders at work , Apress, 2009 </cite> Trotz des Zitats bin ich nicht vorbehaltslos nur pro-C; aber wo er Recht hat, hat der alte Bartträger ins Schwarze getroffen.
>> Da gibt sich aber jemand Mühe, die Diskussion zu stören. ;-) > > Wie "stören"? Das sieht hier aus wie das Internet nach dem > Netzwerkdurchdringungsgesetz ... :-D oder die Moderatoren waren wiedermal nicht mit dem selbst gewählten Automatismus zufrieden und haben von Hand den GarbageCollector angeschubst.
Beitrag #5039852 wurde von einem Moderator gelöscht.
Beitrag #5039854 wurde von einem Moderator gelöscht.
W.S. schrieb: > Gleiche Interfaces sind genau dort von Vorteil, wo man es mit immer > wieder gleichartigen Datenströmen zu tun hat, also serielle Interfaces > aller Art, SDIO, Grafik-Aufbau in einen Bildspeicher für > Display-Aufgaben und dergleichen. Das sowieso. > Aber schon bei den Timern und noch viel mehr bei den schieren GPIO's > hört das komplett auf. Das, was dort stattfindet, ist eigentlich _immer_ > derart projektabhängig, daß es absolut kontraproduktiv wäre, dort deinen > Gedanken in die Tat umzusetzen. Stattdessen braucht es Treiber, die das > jeweilige Problem direkt in eine höhere Ebene umsetzen. > > Also mal ganz vulgär: > nicht "SetzePin(Port,Nummer,Zustand);" > sondern "SchalteMotorEin();" ...oder eben: "motor.einschalten();". Das läßt sich mit einfacher Vererbung ganz einfach, elegant und kostenlos umsetzen. Das bedarf nur einer simplen Elternklasse, die einen Pin abstrahiert -- und ist dann mit einer anderen Elternklasse, die dasselbe Interface auf einer anderen Controllerfamilie implementiert, sogar portabel.
:
Bearbeitet durch User
Beitrag #5039861 wurde von einem Moderator gelöscht.
Beitrag #5039868 wurde von einem Moderator gelöscht.
Beitrag #5039872 wurde von einem Moderator gelöscht.
Sheeva P. schrieb: > ...oder eben: "motor.einschalten();". Das läßt sich mit einfacher > Vererbung ganz einfach, elegant und kostenlos umsetzen. Es läßt sich auch ohne Vererbung einfach, elegant und kostenlos umsetzen. KISS und YAGNI gilt auch für Tools.
Nop schrieb: > Sheeva P. schrieb: > >> ...oder eben: "motor.einschalten();". Das läßt sich mit einfacher >> Vererbung ganz einfach, elegant und kostenlos umsetzen. > > Es läßt sich auch ohne Vererbung einfach, elegant und kostenlos > umsetzen. KISS und YAGNI gilt auch für Tools. Was ist an Vererbung kompliziert? Naja, es geht ja auch ohne: durch Komposition und generische Typen. Ist aber wohl auch zu kompliziert ...
Beitrag #5039899 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Was ist an Vererbung kompliziert? Wieder ein Konzept mehr, das man nicht braucht, also weg damit. Zudem baut man sich dann nicht mit Diamant-Hierarchien in die Ecke. Hauptnachteil ist, daß man nicht stundenlang beim Käffchen über Scheinprobleme wie is-a vs. has-a debattieren kann. > Naja, es geht ja auch ohne: durch Komposition und generische Typen. Braucht man auch nicht, um einen Motor einzuschalten.
Peter Gerlich schrieb im Beitrag #5039861: > avr schrieb: >> lässt sich wunderbar abstrahieren > > ungleich > > Torsten R. schrieb: >> kann man mit C++ ... machen, das ist aber viel Arbeit Für dich gibt es auch nur schwarz und weiß? Mit C++ hat man ein mächtiges Werkzeug zur Abstraktion, vieles kann man sogar zur Compilezeit machen. Natürlich hängt der Arbeitsaufwand mit dem Abstraktionsgrad zusammen. Eine einfache Klasse, welche ein Peripheriebaustein eines speziellen Controllers abstrahiert ist deshalb nicht übermäßig schwer. Wobei ich mich frage, wie man überhaupt auf diesen Zug kommen kann. Abstraktion ist ebenso in C möglich. Und auch dort kann man es übertreiben. Da wird es jedoch sehr viel schneller hässlich, wo es in C++ noch elegante Möglichkeiten gibt. Unter anderem auch, weil das sehr mächtige Templatesystem in C nicht vorhanden ist. => Ein Vorteil von C++ ist nicht die Abstraktion, sondern die Möglichkeit deutlich besser und eleganter abstrahieren zu können. Und so lange hier keine widerspricht bleibe ich bei der Behauptung, dass die meisten C++-Kritiker hier mit der Sprache Probleme haben. Und zwar nicht mit der Syntax, sondern mit den Paradigmen. Denn die Argumente hier sind nur noch zu schwer, zu komplex, braucht man nicht oder irgendwelche Mythen der Overhead. @Nop Du bestätigst mich gerade. Wenn man OOP nicht kennt, dann kann man sie auch nicht brauchen. Wenn man sie als sinnvolles Paradigma akzeptiert, erkennt man auch einen Mehrwert in C++.
Sheeva P. schrieb: > oder eben: "motor.einschalten();". Das läßt sich mit einfacher > Vererbung ganz einfach, elegant und kostenlos umsetzen. Das bedarf nur > einer simplen Elternklasse, die einen Pin abstrahiert -- und ist dann > mit einer anderen Elternklasse, die dasselbe Interface auf einer anderen > Controllerfamilie implementiert, sogar portabel. Aber genau dass geht in C genauso gut. In C++ gibt es halt nur mehr (Austrucks-)Möglichkeiten, die im Zweifel auch performanter sind. Nur sind sie halt nicht immer so gut lesbar und jeder favorisiert einen anderen Ansatz.
Beitrag #5039908 wurde von einem Moderator gelöscht.
Nop schrieb: > Wilhelm M. schrieb: > > >> Naja, es geht ja auch ohne: durch Komposition und generische Typen. > > Braucht man auch nicht, um einen Motor einzuschalten. Klar, geht ja auch mit dem Faustkeil (s.o.).
Beitrag #5039911 wurde von einem Moderator gelöscht.
Achim S. schrieb: > Sheeva P. schrieb: >> oder eben: "motor.einschalten();". Das läßt sich mit einfacher >> Vererbung ganz einfach, elegant und kostenlos umsetzen. Das bedarf nur >> einer simplen Elternklasse, die einen Pin abstrahiert -- und ist dann >> mit einer anderen Elternklasse, die dasselbe Interface auf einer anderen >> Controllerfamilie implementiert, sogar portabel. > > Aber genau dass geht in C genauso gut. In C++ gibt es halt nur mehr > (Austrucks-)Möglichkeiten, die im Zweifel auch performanter sind. Woher nimmst Du diese Behauptung???
Ach ja, wo OOP wirklich Sinn ergibt, das ist, wenn man nicht eingebildete Pseudo-Objekte baut, nur um OOP zu machen, sondern wenn tatsächlich dynamisch Objekte erzeugt werden und verschwinden, die auch tatsächlich eigenes Benehmen haben. Simulationen sind da wichtig (da kommt OOP ja her), und damit auch heutige Spiele, weil die einzelnen Elemente jedes für sich agieren und entstehen sowie verschwinden können. Und natürlich GUIs, wo das genauso ist. Aber Motoren und ihre Pins sind, wo sie sind, und da bleiben sie auch. Motoren entstehen nicht dynamisch und verschwinden wieder. Gaspedale und Bremsen auch nicht.
Beitrag #5039919 wurde von einem Moderator gelöscht.
Nop schrieb: > Ach ja, wo OOP wirklich Sinn ergibt, das ist, wenn man nicht > eingebildete Pseudo-Objekte baut, nur um OOP zu machen, sondern wenn > tatsächlich dynamisch Objekte erzeugt werden und verschwinden, die auch > tatsächlich eigenes Benehmen haben. Sag mal, liest Du überhaupt die Beiträge hier? OOP im engeren Sinn ist zwar ein Möglichkeit, ich habe aber oben schon zigmal gesagt, dass andere Konzeote viel wichtiger sind. Mittlerweile denke, Du weißt gar nicht, was bestimmte Begriffe bedeuten ... > Aber Motoren und ihre Pins sind, wo sie sind, und da bleiben sie auch. > Motoren entstehen nicht dynamisch und verschwinden wieder. Gaspedale und > Bremsen auch nicht. Genau! Wie gesagt, OOP im engeren Sinn ist nicht das Einzige, was C++ beherrscht (s.o, x-te Iteration).
Beitrag #5039931 wurde von einem Moderator gelöscht.
Beitrag #5039933 wurde von einem Moderator gelöscht.
Beitrag #5039934 wurde von einem Moderator gelöscht.
Beitrag #5039936 wurde von einem Moderator gelöscht.
Beitrag #5039939 wurde von einem Moderator gelöscht.
Nop schrieb: > sondern wenn > tatsächlich dynamisch Objekte erzeugt werden und verschwinden, die auch > tatsächlich eigenes Benehmen haben. OOP hat erst mal nichts mit dem Erzeugen von Objekten zu tun. Es kann auch alles statisch bleiben. Und daher kann man auch einen UART wunderbar in eine statische Klasse stecken. Wenn man möchte, kann diesem UART durch Vererbung beliebige Features hinzufügen (Puffer, Protokolle) und diese Klasse beliebig oft verwenden. Wenn einem das nicht passt, kann man auch in C++ ohne OO programmieren und freut sich z.B. über Templates, welche Berechnungen zur Compilezeit durchführen oder was auch immer.
avr schrieb: > Nop schrieb: >> sondern wenn >> tatsächlich dynamisch Objekte erzeugt werden und verschwinden, die auch >> tatsächlich eigenes Benehmen haben. > > OOP hat erst mal nichts mit dem Erzeugen von Objekten zu tun. Es kann > auch alles statisch bleiben. Und daher kann man auch einen UART > wunderbar in eine statische Klasse stecken. Wenn man möchte, kann diesem > UART durch Vererbung beliebige Features hinzufügen (Puffer, Protokolle) > und diese Klasse beliebig oft verwenden. Wenn einem das nicht passt, > kann man auch in C++ ohne OO programmieren und freut sich z.B. über > Templates, welche Berechnungen zur Compilezeit durchführen oder was auch > immer. Auch das habe ich schon x-mal hier geschrieben, nur mich beschleicht das Gefühl, dass nicht verstanden wird, was z.B. constexpr-lambdas sind ...
Beitrag #5039955 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Genau! Wie gesagt, OOP im engeren Sinn ist nicht das Einzige, was C++ > beherrscht (s.o, x-te Iteration). Ja, die Modewellen macht C++ alle mit. Vererbung war der Hype in den 90ern, heute werden dem C++11-beinigen Octopus auch noch funktionale Konzepte reingenagelt. Und der Scope wächst, wächst und wächst. Ich ziehe es vor, wenn ich direkt Zeile für Zeile lesen kann, was genau der Code tut, besonders wenn er nicht von mir ist. Das ist bei C++ schon wegen der Fragmentierung problematisch. Außer natürlich für die Profis des Forums, die die C++-Standards von 1998 bis 2017 zu 100% beherrschen, STL und Boost ebenso, mitsamt den Nuancen für diverse FAST identische Wege, dasselbe zu erreichen, aber die stets den richtigen nehmen. Die Realität: MISRA-C wurde geschaffen, weil sogar der C-Standard zu komplex ist. Und wieso hat man die Leute nicht einfach alle rausgeworfen, C-Programmierer sollte es doch erst recht geben? Weil das Domänenwissen das Entscheidende ist und nicht das Programmieren.
Beitrag #5039959 wurde von einem Moderator gelöscht.
Beitrag #5039961 wurde von einem Moderator gelöscht.
Nop schrieb: > Sheeva P. schrieb: > >> ...oder eben: "motor.einschalten();". Das läßt sich mit einfacher >> Vererbung ganz einfach, elegant und kostenlos umsetzen. > > Es läßt sich auch ohne Vererbung einfach, elegant und kostenlos > umsetzen. KISS und YAGNI gilt auch für Tools. Kostenlos, Kunststück, wenn C die Kostenreferenz ist, einfach auch, solange man nur diese einfache Instruktion betrachtet, aber... elegant? Es ist ganz sicher auch eine Frage des persönlichen Empfindens (und der Fähigkeiten und Kenntnisse) aber für mich sieht "SchalteMotorEin()" eher unelegant aus. Die unnatürlichen Bandwurmworte unterstützen den Lesefluß jedenfalls nicht. Aber, weißt Du, ich glaube wir nähern uns dem Kern der Mißverständnisse zwischen uns beiden, den de facto ist die Vererbung extrem einfach, so man sie einmal verstanden hat. Daß Du sie als kompliziert ansiehst, läßt mich vermuten, daß das bei der -- warum auch immer -- nicht der Fall ist. Wenn meine Vermutung zutrifft, dann ist klar, warum wir immer an einander vorbei reden: weil ich C++ kenne und seine äußerst positiven Effekte in diversen Umgebungen ausnutze, während das bei Dir nicht der Fall ist und Du zuerst nur die Lernhürde siehst, die Du zuvor einmal überwinden müßtest, um die positiven Effekte kennenzulernen -- und weil Du mir nicht glauben willst, daß es diese positiven Effekte gibt und daß sie groß genug sind, um die nötige Lerninvestition sehr schnell zu amortisieren. Was ich dann allerdings nicht verstehe, ist, warum Du nicht einfach bei Deiner Lieblingssprache bleibst und die C++-Freunde ihr Ding machen läßt, sondern explizit gegen C++ und damit gegen etwas argumentierst, das Du im Grunde genommen gar nicht beurteilen kannst (und willst). Darauf deutet jedenfalls auch hin, daß Du so gar keine eigenen Sachargumente in diese Diskussion eingebracht hast, sondern immer wieder auf andere verweist und Dich ansonsten auf die Behauptung zurückziehst, C++ sei (zu) kompliziert. Naja, nichts für ungut, vielleicht liege ich ja auch flashc. Dann würden mich Deine sachlichen Argumente allerdings umso brennender interessieren.
Beitrag #5039964 wurde von einem Moderator gelöscht.
Beitrag #5039970 wurde von einem Moderator gelöscht.
Beitrag #5039973 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Aber genau dass geht in C genauso gut. In C++ gibt es halt nur mehr >> (Austrucks-)Möglichkeiten, die im Zweifel auch performanter sind. > > Woher nimmst Du diese Behauptung??? welche meinst Du? Dass die Abstrahierung von motor.einschalten() in C genauso gut geht? weil ich es so mache. Kann ich Dir gerne konkrete Beispiele liefern Dass es mehr Ausdrucksmöglichkeiten in C++ gibt? Das ist doch gerade die Quintessenz der Diskussion hier. Das es in C++ im Zweifel performanter ist? Weil die meisten Ausdrucksmöglichkeiten zur Compilezeit in nichts zerfallen. Im Video oben von Dan Saks über C++ zeigt er auch genau das. (Da. wo inline in beiden Sprachen das Optimum ist).
Beitrag #5039980 wurde von einem Moderator gelöscht.
Nop schrieb: > Wilhelm M. schrieb: > >> Genau! Wie gesagt, OOP im engeren Sinn ist nicht das Einzige, was C++ >> beherrscht (s.o, x-te Iteration). > > Ja, die Modewellen macht C++ alle mit. Vererbung war der Hype in den > 90ern, heute werden dem C++11-beinigen Octopus auch noch funktionale > Konzepte reingenagelt. Und der Scope wächst, wächst und wächst. Wir haben 2017 und OOP gibt es immer noch: 27 Jahre nach Deiner Rechnung (eigentlich schon viel älter) - ist das noch ein Hype oder hat das seine Gründe. Aber: OOP im engeren Sinn (etwas anderes scheinst Du nicht zu kennen) ist nicht das Mittel der Wahl für µC (aus ganz verschiedenen Gründen). > Ich ziehe es vor, wenn ich direkt Zeile für Zeile lesen kann, was genau > der Code tut, besonders wenn er nicht von mir ist. Ok, das spricht eigentlich für Assembler, oder? > Das ist bei C++ schon > wegen der Fragmentierung problematisch. Was bezeichnest Du als Fragmentierung?
Nop schrieb: > Wilhelm M. schrieb: > >> Was ist an Vererbung kompliziert? > > Wieder ein Konzept mehr, das man nicht braucht, also weg damit. Du hast Recht: man braucht das Konzept nicht, genauso, wie man keine Spül- und keine Wachmaschine braucht. Diese Dinge machen das Leben zwar in vielen Bereichen wesentlich einfacher und müheloser, aber Du kannst natürlich gern auf diese Annehmlichkeiten verzichten. Warum Du dann allerdings andere dazu bringen willst, ebenfalls zu verzichten, bleibt wohl Dein Geheimnis. > Zudem baut man sich dann nicht mit Diamant-Hierarchien in die Ecke. > Hauptnachteil ist, daß man nicht stundenlang beim Käffchen über > Scheinprobleme wie is-a vs. has-a debattieren kann. Schon wieder diese konstruierten Probleme -- beides ist mir in > 20 Jahren objektorientierter Softwareentwicklung noch nie passiert.
Achim S. schrieb: > Wilhelm M. schrieb: >> Aber genau dass geht in C genauso gut. In C++ gibt es halt nur mehr >>> (Austrucks-)Möglichkeiten, die im Zweifel auch performanter sind. >> >> Woher nimmst Du diese Behauptung??? > > welche meinst Du? Ups, hatte Dich so verstanden, das Du C im Vorteil siehst. Mein Fehler ...
Beitrag #5039987 wurde von einem Moderator gelöscht.
Beitrag #5039992 wurde von einem Moderator gelöscht.
Sheeva P. schrieb: > Kostenlos, Kunststück, wenn C die Kostenreferenz ist, einfach auch, > solange man nur diese einfache Instruktion betrachtet, aber... elegant? Geschmackssache, wie Du schon sagst. Ich finde es elegant, wenn die Anforderungen möglichst einfach umgesetzt werden, und die Forderung lautet normalerweise bloß, daß bei dem und dem Ereignis der Pin sowieso innerhalb einer bestimmten Zeit gesetzt werden muß. Wenn man zusätzlich zu dem Pinsetzen noch haufenweise Abstraktionen draufsetzt, hat das für mich keinen Mehrwert. KISS und YAGNI. > Die unnatürlichen Bandwurmworte unterstützen den Lesefluß > jedenfalls nicht. Man kann auch Unterstriche reinmachen, das ist kein wesentlicher optischer (!) Unterschied zu einem Punkt. > Daß Du sie als kompliziert ansiehst, läßt > mich vermuten, daß das bei der -- warum auch immer -- nicht der Fall > ist. Ich habe das oben schon erklärt. Das ständige Beharren von C++-Programmierern, daß Leute, die unter "einfach" etwas anderes verstehen, eben blöd sein müssen, macht diese Sichtweise nicht wahrer. Ich verstehe unter "einfach" nicht, daß man am Ende zwei Zeilen Code schreibt, hinter denen Tonnen an compiler magic stehen. Ich finde das im Gegenteil umständlich, weil das Hinschreiben zwar leicht ist, aber das Nachvollziehen, was exakt an Binärcode rausfällt, ist umso schwieriger. Das wird in C++-Kreisen übrigens gerne als "C hacker syndrome" diskreditiert. (Ach ja, und wieso ich nicht gleich Assembler nehme: weil man den Code nicht portieren kann, und weil es nervig wird, wenn man mehrere Architekturen gleichzeitig bearbeitet.) > Was ich dann allerdings nicht verstehe, ist, warum Du nicht einfach bei > Deiner Lieblingssprache bleibst und die C++-Freunde ihr Ding machen > läßt Auf gut deutsch: "halt einfach die Klappe". Ja, so kann man natürlich in Threads versuchen, Leuten einzureden, C++ sei mehr oder weniger alternativlos heutzutage. Du wirst damit klarkommen müssen, daß Leute in entsprechenden Threads sagen, daß 90% dessen, worauf Du stehst, in ihren Augen überflüssig ist, weil nicht notwendig zum Lösen typischer embedded-Aufgaben. > C++ sei (zu) kompliziert. Das ist es auch, und mit der Meinung stehe ich auch beileibe nicht alleine. Selbstverständlich gehst Du auch beharrlich nicht darauf ein, daß in einer Branche, wo MISRA-C nötig ist, weil schon C zu komplex ist, C++ der reine Wahnsinn wäre.
Da hatte doch gerade jemand gefragt, wozu man diesen Unsinn wie constexpr-lambdas braucht ... eigentlich eine gute Frage, für jemanden, der offensichtlich nur den Präprozessor kennt. Leider ist der Beitrag jetzt weg, und ich weiß nicht mehr genau, was gefragt wurde ...
Beitrag #5039996 wurde von einem Moderator gelöscht.
Beitrag #5039998 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Ok, das spricht eigentlich für Assembler, oder? Nein, siehe Posting vor diesem. > Was bezeichnest Du als Fragmentierung? Daß außerhalb dieses Forums die meisten C++-Programmierer nicht die Standards von 1998 bis 2017 alle zu 100% kennen mitsamt allen Feinheiten von STL und Boost. Siehe der Kommentar von Thompson. In der Realität zerfällt das in Dialekte, wegen Subsetting, die aber zueinander inkompatibel sind. Das ist dann toll, wenn Du neue Leute in die Firma kriegst, die einen anderen Dialekt sprechen. Die verstehen zunächst einmal nichtmal den Code auf sprachlicher Ebene, geschweige denn auf inhaltlicher. Längere Einarbeitung heißt höhere Kosten. Noch viel besser wird das, wenn eine Firma von einer anderen aufgekauft wird, da kommt dann Freude auf.
Beitrag #5040004 wurde von einem Moderator gelöscht.
Beitrag #5040007 wurde von einem Moderator gelöscht.
Beitrag #5040012 wurde von einem Moderator gelöscht.
Vincent H. schrieb: > @Wilhelm M. & Sheeva Plug > > You argue, you lose. ... loose. Macht nix, ich bin ein guter Verlierer ;-)
Oliver J. schrieb: > @Nop: > Hast du denn schon mal ernsthaft mit C++ gearbeitet? Das war doch wohl eine rhetorische Frage, bei den praxisfernen Argumenten und Beispielen die von ihm kommen.
@nop: Hast du schon mal ernsthaft mit C++ gearbeitet? Johannes S. schrieb: > Oliver J. schrieb: >> @Nop: >> Hast du denn schon mal ernsthaft mit C++ gearbeitet? > > Das war doch wohl eine rhetorische Frage, bei den praxisfernen > Argumenten und Beispielen die von ihm kommen. Ich wollte nur auf Nummer-Sicher gehen ;-)
Beitrag #5040022 wurde von einem Moderator gelöscht.
Ach ja, und vermissen tue ich in C ganz andere Sachen: - das inline-Keyword ist völlig nutzlos, weil es ein unverbindlicher Vorschlag an den Compiler ist. Um wirklich inline zu kriegen, muß man mit proprietären Erweiterungs-Hacks arbeiten. - das Gegenteil, ein Verbot des Inlinens für eine spezifische Funktion, gibt es nur mit Erweiterungshacks. - Auch das Markieren einer Funktion als Interruptroutine oder als "used" gibt's nicht standardmäßig. - computed goto ebenfalls nicht. - die ursprünglichen Standardfunktionen wie strcpy, scanf & Co sind schlampige Hacks und auch bei korrekter Verwendung ein Sicherheitsrisiko. Immerhin gibt's da neue. - es gibt keine portable Methode, wie man auf PC-Systemen feststellen kann, ob eine Taste gedrückt wurde, ohne sie auszulesen, also sowas wie kbhit(). - die Operatorreihenfolge ist z.T. sehr ungeschickt, beispielsweise mit == und binären Logik-Operatoren, welche sich da völlig anders als die logisch gesehen ähnlichen arithmetischen verhalten.
Oliver J. schrieb: > @Nop: > Hast du denn schon mal ernsthaft mit C++ gearbeitet? Hat sich für kleinere Geschichten auf minimalstes C mit Klassen begrenzt, und das fand ich schon daneben. Ist zum Glück auch schon ne ganze Weile her. Ansonsten reicht es mir, wenn ich alle paar Jahre wieder lese, was für abgefahrene Sachen jetzt schon wieder eingebaut werden, schon verstärkt sich meine Abneigung. Less is more, und etwas ist nicht perfekt, wenn man nichts mehr hinzufügen kann, sondern wenn man nichts mehr wegnehmen kann, ohne daß es zerbricht. Das ist aber so ziemlich das Gegenteil von C++.
Hier herrscht ja ein brutal rauer Ton. Ich fände es besser wenn wir wieder zurückkehren könnten zu einer sachlichen Diskussion.
Beitrag #5040031 wurde vom Autor gelöscht.
Beitrag #5040041 wurde von einem Moderator gelöscht.
Nop schrieb: > Ach ja, und vermissen tue ich in C ganz andere Sachen: > > - das inline-Keyword ist völlig nutzlos, weil es ein unverbindlicher > Vorschlag an den Compiler ist. Um wirklich inline zu kriegen, muß man > mit proprietären Erweiterungs-Hacks arbeiten. Naja, der Sinn des inline-Keywords ist ja entgegen seinem Namen auch ein anderer - auch in C!
Wilhelm M. schrieb: > Naja, der Sinn des inline-Keywords ist ja entgegen seinem Namen auch ein > anderer Das beschreibt das Problem ganz gut, und sowas ist einfach vom Grundsatz her schon daneben.
Beitrag #5040047 wurde von einem Moderator gelöscht.
Wir befinden uns im Jahr 35 nach C. Die ganze Welt hat erkannt, dass eine gute Programmiersprache prozeduale, funktionale und objektorientierte Ansätze unterstützen sollte. Die ganze Welt? Nein, ein von unbeugsamen C Jüngern bevölkertes Dorf hört nicht auf dem Eindringling Widerstand zu leisten!
Nop schrieb: > Wilhelm M. schrieb: > >> Genau! Wie gesagt, OOP im engeren Sinn ist nicht das Einzige, was C++ >> beherrscht (s.o, x-te Iteration). > > Ja, die Modewellen macht C++ alle mit. Vererbung war der Hype in den > 90ern, heute werden dem C++11-beinigen Octopus auch noch funktionale > Konzepte reingenagelt. Die gab es schon in C, in C++ wurden sie lediglich noch einmal ein wenig vereinfacht und verfeinert. > Ich ziehe es vor, wenn ich direkt Zeile für Zeile lesen kann, was genau > der Code tut, besonders wenn er nicht von mir ist. Das kann ich auch bei C++-Code. > Das ist bei C++ schon wegen der Fragmentierung problematisch. Wenn man nicht aufpaßt, ist die bei C wesentlich größer als bei C++.
Beitrag #5040054 wurde von einem Moderator gelöscht.
Achim S. schrieb: > Dass die Abstrahierung von motor.einschalten() in C genauso gut geht? > weil ich es so mache. Kann ich Dir gerne konkrete Beispiele liefern Du baust Dir ein Struct mit einem Funktionszeiger?
Sheeva P. schrieb: > Wenn man nicht aufpaßt, ist die bei C wesentlich größer als bei C++. Nein, denn die Sprache ist klein genug. Zudem gibt's obendrein, um das noch kleiner zu machen, ja auch noch MISRA-C. Ein Problem kann man natürlich anderweitig haben, wie in jeder Programmiersprache, wenn man sich Spaghetti baut. Das ist dann aber keine Fragmentierung bereits auf sprachlicher Ebene. C garantiert einem schließlich nicht, daß man sein Programm sinnvoll aufbaut. Das tut C++ aber auch nicht. Das tut überhaupt keine Sprache. Allenfalls garantiert einem Brainf*ck umgedreht, daß man es nicht sinnvoll aufbauen KANN. ;-)
Beitrag #5040073 wurde von einem Moderator gelöscht.
Hmmm..., wenn man immer die "ideale" Sprache nutzen will, dann kann man wohl für jedes wechselnde Projekt auch immer die Programmiersprache wechseln um ein Quäntchen an Perfomance, Leistungsfähigkeit, Funktionen, Ressourcenverbrauch, etc... zu gewinnen. Ob es sinnvoll ist, alle x-Sprachen zu kennen, das halte ich eventuell übertrieben und finde es besser wenn man 1-2-3 Sprachen beherrscht, da aber umso besser. Oder? Für kleine Programme (z.B. auf einem STM32) habe ich schon C genommen. Ich frage mich, ob und für welchen Zweck C++ oder C# für einen STM32 besser wäre? (Ich frage nicht um C++ oder C# schlecht zu machen, sondern weil ich mich nicht damit auskenne). Gern möchte ich lernen/können einen STM32 mit Touch-Display zu programmieren (z.B. für eine Haussteuerung). Welche Sprache ist da empfehlenswert? Ebenso einen Raspberry mit Touch-Display und kleiner Visualisierung oder größeren Aufgaben (Linux/Windows Betriebssystem?). Was nimmt man da für eine Sprache? Wie sieht es auf Windows-PC aus, welche ist da die geeigneteste Sprache um grfische Oberflächen zu programmieren? Nun es ist nicht leicht, eventuell werden mir nun 10 Sprachen empfhlen, aber so viele möchte ich nicht lernen. 2 oder max. 3 Sprachen, mehr nicht, damit sollte sich alles unter einen Hut bringen lassen.
Beitrag #5040081 wurde von einem Moderator gelöscht.
W.S. schrieb: > Torsten R. schrieb: >> Naja, wenn ich auf jeder Plattform schon mal das gleiche Interface zu >> GPIOs und Timern hätte, wäre doch schon viel gewonnen. > > Ach wo. > > Gleiche Interfaces sind genau dort von Vorteil, wo man es mit immer > wieder gleichartigen Datenströmen zu tun hat, also serielle Interfaces > aller Art, SDIO, Grafik-Aufbau in einen Bildspeicher für > Display-Aufgaben und dergleichen. Ja, da bin ich doch total bei Dir. Das habe ich doch sogar im nächsten Satz geschrieben: > Ich denke, soetwas kann sehr gut funktionieren, wenn ich meine Bedürfnisse an die Hardware möglichst konkret definieren kann. Mein Beispiel war eine PWM. Dein Beispiel ist ein Motor. Wenn ich eine effektive Abstraktion von der Hardware haben möchte, dann kann ich bei der Abstraktion der Hardware halt nicht bei Timer und GPIO aufhören und mir eine Library bauen, die auf der GPIO und Timer Abstraktion aufbauend eine PWM implementiert, weil es Controller gibt, die eine PWM in Hardware implementieren. Aber: Die trotzdem wäre für mich eine Abstraktion von so häufig genutzten Peripherals wie GPIO und Timer schon ein Fortschritt, weil ein GPIO-Pin halt häufig direkt auf diesem niedrigen Level genutzt wird: Lampe An, Lampe Aus. > Stattdessen braucht es Treiber, die das > jeweilige Problem direkt in eine höhere Ebene umsetzen. Genau! Ich möchte angeben können, dass ich eine UART benutzen möchte, dass die an folgende Pins angeschlossen ist, das die Konfiguration 9600,8N1 ist, etc.. (Mir völlig egal, ob der Controller eine UART hat, oder die Library das mit Bitbanging machen muss. Ich möchte nicht stundenlang debuggen, um raus zu finden, dass irgend ein Clock-Enable Bit gesetzt werden muss usw.) Ich möchte einen GATT Server mit folgenden Satz an Funktionen, die aufgerufen werden, wenn ein Client auf die Characteristiken zugreift. (Ich möchte nicht 250 Zeilen C-Code schreiben müssen, um damit den Inhalt einer im RAM liegenden Tabelle zu füllen, die nach der Initialisierung und wärend der ganzen Laufzeit konstant bleibt [soetwas gehört ins ROM]). > Kurzum, der Versuch, auf niedrigster Ebene zu vereinheitlichen, ist > unproduktiv. Sowas muß man auf einer angemessenen höheren Ebene machen. Jein. Abstraktion auf unterster Ebene macht Sinn, wenn es Anwendungen auf der Ebene gibt (Lämpchen an, Lämpchen aus). Ansonsten bin ich ganz bei Dir und meine mit C++ das passende Werkzeug dafür gefunden zu haben (Beispiel: https://github.com/TorstenRobitzki/bluetoe).
Ich für meinen Teil finde es jetzt nicht wirlich viel schwieriger mich in C++-Code einzuarbeiten. Es ist erfahrungsgemäß bei gleicher Codequalität ähnlich schwer, wenn man die Sprache und eventuell verwendete Pattern kennt. Da gilt denke ich für jede Sprache. Das lässt sich glaube ich auch gut auf die menschliche Sprache anwenden: Wenn man eine Fremdsprache nicht so gut beherrscht wie seine Muttersprache, dann tut man sich da natürlich schwerer ;). Wenn also jemend C++ beherrscht, kann er es denke ich auch hernehmen. Besonders, wenn man eine objektorientierte Lösung designt hat. Das in C umzusetzen ist nicht schön. Haben wir beruflich mal für ein Kommunikationsframework (> 2 Mannjahre) gemacht, da ein konsumierendes Projekt in C war. Bei uns im Team hat ganz ehrlich niemand Lust die Problemlösungen in C abzubilden. Das liegt aber wahrscheinlich auch daran, dass wir mittlerweile architekturgetrieben die Software hochziehen.
Sprachenlerner schrieb: > Gern möchte ich lernen/können einen STM32 mit Touch-Display zu > programmieren GUI und C ist ein ziemlicher Horror, also jedenfalls C ist für den Zweck draußen.
Sprachenlerner schrieb: > Wie sieht es auf Windows-PC aus, welche ist da die geeigneteste Sprache > um grfische Oberflächen zu programmieren? Da ist C# mit WPF oder WinForms denke ich durchaus einen Blick wert. C++ mit qt könnte man eventuell auch in Betracht ziehen. Grüße Oliver
Torsten R. schrieb: > (Ich möchte nicht 250 Zeilen C-Code schreiben müssen, um damit den > Inhalt einer im RAM liegenden Tabelle zu füllen, die nach der > Initialisierung und wärend der ganzen Laufzeit konstant bleibt [soetwas > gehört ins ROM]). Ich hab in so einem Fall diesen Prozeß beim Build auf dem Host gemacht und dann mit xxd ein C-File erzeugt, was ich einfach ins Projekt reincompiliert habe. Dadrin ist dann ein Array mit den nötigen Binärdaten, das man ins ROM verfrachten kann.
Also, ehrlich! Eure Diskussion in Ehren. Trotzdem würde ich es aber toll finden wenn wir alle vielleicht diese Diskussion in den Rahmen eines Workshops hinbiegen könnten. Damit ließe sich viel Positives erreichen. Z.B. wurde einige Beiträge zurück bemerkt wie grottig die Arduino Bibliotheken zum Teil wären. Könnte man nicht ein paar Beispiele von guten und schlechteren Ansätzen aussuchen und dann hier durch gehen wie man es eben besser machen könnte? Die meisten kennen sich ja mit AVR aus und wäre wegen der relativen Leistungsschwachheit eine gute Platform effiziente Codebeispiele zu testen. Viele würden das bestimmt sehr lehrreich finden. Was wirklich gut wäre, kollektiv ein kleines Handbuch zu erstellen über die Do's und Don't's von C++ auf kleineren uC und GCC mit Beispielen als gemeinsame Platform die allen zugänglich ist. Ich bin der Meinung, daß praktischer Einsatz von C++ weit lehrreicher für viele nicht-professionelle Programmierer wäre anstatt sich durch zum Teil schwer verständliche C++ Literatur und Handbücher durchquälen zu müssen. Erst durch Probieren verschiedenster Ansätze gewinnt man ein intuitives Gefühl dafür was empfehlenswert ist und was nicht. Nicht alle haben Informatik studiert und viele Fachliteratur ist für Nicht-Informatiker nur schwer in allen Konsequenzen und Feinheiten verständlich Gerade hier im Forum könnte man diesbezüglich (trotz viel Zweifels) viel erreichen. Zerreisst mich jetzt aber nicht gleich in der Luft, bitte;-) Schönen Abend noch, Gerhard
Meiner Meinung nach kann man C++ ruhig bis zu den Klassen hin nutzen, man kann schön alle Funktionen und Variablen in einer Klasse unterbringen, das geht in C nicht mehr so komfortabel. Wenn man also C++ bis zu den Klassen hin anwendet ohne Vererbung und Mehrfachverrbung und was es sonst noch alles gibt, dann ist C++ vom Sprachumfang her nicht größer als C, so sehe ich das zumindest. Im Grunde genommen spielt es bei kleinen Hobbyprojekten keine Rolle ob C oder C++, diese Sprachen sind erst im industriellen Einsatz interessant, weil dort kein wildes Sammelsurium sondern eine Einheitlichkeit vorhanden sein muss. Man kann also um schnelle Erfolge zu erzielen auch ruhig Arduino nehmen, man muss es sich nicht unnötig schwer machen, wobei C oder C++ (bis zur genannten Grenze) wirklich nicht kompliziert sind, man muss sich nur die Zeit nehmen es zu lernen.
Ich freu mich schon auf den nächsten Thread, in dem jemand versucht mit dem C-Preprozessor zu rechnen. Dabei gibt es in C++ constexpr, das ab C++14 im fast normalen Sprachumfang die Programmierung zur Compilezeit erledigt. Und dann wird versucht
1 | #define PORT D
|
2 | #if PORT==D
|
3 | #elif PORT==A
|
4 | #endif
|
ohne zu ahnen, wie minimal der Funktionsumfang dieser Sprache ist. Und dabei gäbe es "conditional compiling" via "constexpr if", wenn man es wissen wollte. Hauptsache scheiß OOP.
:
Bearbeitet durch User
Nop schrieb: > Sheeva P. schrieb: >> Kostenlos, Kunststück, wenn C die Kostenreferenz ist, einfach auch, >> solange man nur diese einfache Instruktion betrachtet, aber... elegant? > > Geschmackssache, wie Du schon sagst. Ich finde es elegant, wenn die > Anforderungen möglichst einfach umgesetzt werden, und die Forderung > lautet normalerweise bloß, daß bei dem und dem Ereignis der Pin sowieso > innerhalb einer bestimmten Zeit gesetzt werden muß. Ja, wenn man nur das Ereignis und das Pinwackeln betrachtet. Aber wenn man auch Lesbarkeit, Wartbarkeit und Kompaktheit des Codes in die Betrachtung einbezieht, dann, ganz eindeutig: nein. Denn die Anforderungen lassen sich mit C++ ganz genauso einfach umsetzen, dafür aber viel kompakter und daher mit einer höheren Les- und Wartbarkeit sowie einer besseren Unterstützung durch die gängigen Programmerwerkzeuge. > Wenn man zusätzlich zu dem Pinsetzen noch haufenweise Abstraktionen > draufsetzt, hat das für mich keinen Mehrwert. KISS und YAGNI. Fällt Dir was auf? Mir schon: der Einzige, der hier von "haufenweiser Abstraktion" redet, bist Du. Entschuldige, aber Du scheinst seltsame Vorstellungen von C++ auf uCs zu haben. Da gibt es meist zu wenig zu abstrahieren, als das von "haufenweise" die Rede sein könnte. So ein GPIO-Pin ist ein GPIO-Pin, und die Anzahl von Operationen, die damit ausgeführt werden können, ist prinzipbedingt recht eng begrenzt. Was stellst Du Dir unter einer "haufenweisen Abstraktion" denn vor? > Man kann auch Unterstriche reinmachen, das ist kein wesentlicher > optischer (!) Unterschied zu einem Punkt. Ja, und dazu darf man dann x-mal denselben Boilerplate schreiben. >> Daß Du sie als kompliziert ansiehst, läßt >> mich vermuten, daß das bei der -- warum auch immer -- nicht der Fall >> ist. > > Ich habe das oben schon erklärt. Das ständige Beharren von > C++-Programmierern, daß Leute, die unter "einfach" etwas anderes > verstehen, eben blöd sein müssen, macht diese Sichtweise nicht wahrer. Du verwechselst Blödheit mit Unkenntnis. Es ist ja gar nicht schlimm, C++ nicht zu kennen und nicht kennenlernen zu wollen. Aber es nicht zu kennen und nicht kennenlernen zu wollen, sondern stattdessen Unsinn darüber zu reden, das erschließt sich mir einfach nicht. > Ich verstehe unter "einfach" nicht, daß man am Ende zwei Zeilen Code > schreibt, hinter denen Tonnen an compiler magic stehen. Sieh an, da sind wir sogar einig. Aber ich verstehe unter einfach auch, daß sich das, was der Code tut, nicht hinter Tonnen winziger, breit über meinen Quellcode verstreuter Fragmente verteilt, der sich nur mit weiteren Tonnen von Kommentaren verstehen und zueinander in Bezug setzen läßt. > Ich finde das im > Gegenteil umständlich, weil das Hinschreiben zwar leicht ist, aber das > Nachvollziehen, was exakt an Binärcode rausfällt, ist umso schwieriger. Ab einer gewissen Komplexität kannst Du das auch in C vergessen, weil dann der Optimizer des Compilers zuschlägt. Genau das macht er übrigens auch mit den meisten syntaktischen Helferlein von C++, die das Leben um so Vieles einfacher und komfortabler machen können. > Selbstverständlich gehst Du auch beharrlich nicht darauf ein, daß in > einer Branche, wo MISRA-C nötig ist, weil schon C zu komplex ist, C++ > der reine Wahnsinn wäre. Während Du mindestens ebenso beharrlich ignorierst, daß die Existenz von Misra-C++ beweist, daß offensichtlich ein Bedarf dafür besteht. Abgesehen davon sehe ich jedoch keine Notwendigkeit, der Aussage zu widersprechen. Schließlich sage ich selbst, daß C komplexer ist, als seine Befürworter behaupten, und (nicht nur für Anfänger) einige böse Klippen bereithält. Darüber hinaus sage ich aber auch, daß C++ eine große Hilfe dabei sein kann, viele dieser Klippen sicher zu umschiffen. Um uns die nächsten beiden Schritte zu ersparen, greife ich kurz vor: Du wirst jetzt korrekterweise behaupten, daß man Komplexität nicht durch das Hinzufügen von noch mehr Komplexität beherrschen kann, woraufhin ich Dir antworte, daß C++ keineswegs komplexer, sondern nur anders ist. ;-)
Carl D. schrieb: > ohne zu ahnen, wie minimal der Funktionsumfang dieser Sprache ist. Sorry, das hat relativ wenig damit zu tun. In diesem Falle waren die Buchstaben nämlich wirklich reiner Präprozessorsalat, weil daraus dann eigentlich Namen wie PORTA oder PIND gebaut werden sollten. Die "A" und "D" haben dabei selbst aber keinerlei eigenen Wert, den man hätte überhaupt irgendwie testen können – da hilft dir auch dein constexpr nichts. Das Ganze ist der in dieser Hinsicht letztlich doch etwas verkorksten AVR-Architektur geschuldet, bei der man nicht sowas wie PORTA->DIR oder PORTA.DIR schreiben kann, sondern eben einen eigenen Namen DDRA stattdessen benutzen muss. Einen solchen Namen zurecht zu zimmern, das kann wirklich nur der Präprozessor (und auch der schon eher mit Tricks).
Wilhelm M. schrieb: > Vincent H. schrieb: >> @Wilhelm M. & Sheeva Plug >> >> You argue, you lose. > > ... loose. Macht nix, ich bin ein guter Verlierer ;-) Nee, "to lose" wäre schon richtig. Aber wir streiten ja nicht, oder?
Nop schrieb: > Nein, denn die Sprache ist klein genug. Ja, und C++ auch. > Zudem gibt's obendrein, um das noch kleiner zu machen, ja auch noch > MISRA-C. ... und Misra-C++. ;-) > Ein Problem kann man > natürlich anderweitig haben, wie in jeder Programmiersprache, wenn man > sich Spaghetti baut. Das ist dann aber keine Fragmentierung bereits auf > sprachlicher Ebene. Auf die Gefahr hin, mich zu wiederholen: schlechten Code kann man in jeder Sprache schreiben. > C garantiert einem schließlich nicht, daß man sein Programm sinnvoll > aufbaut. Das tut C++ aber auch nicht. Das tut überhaupt keine Sprache. > Allenfalls garantiert einem Brainf*ck umgedreht, daß man es nicht > sinnvoll aufbauen KANN. ;-) Das ist allerdings richtig. Allerdings ist die Wahrscheinlichkeit, daß ein fehler- und warnungsfrei übersetztes C++-Programm tut, was es soll, größer als bei einem fehler- und warnungsfrei übersetzten C-Programm.
Nop schrieb: > Daß außerhalb dieses Forums die meisten C++-Programmierer nicht die > Standards von 1998 bis 2017 alle zu 100% kennen mitsamt allen Feinheiten > von STL und Boost. Siehe der Kommentar von Thompson. Das ist eigentlich überhaupt kein Problem, wenn man das Hauptberuflich macht. Die Standards flattern jetzt auch nicht jährlich ins Haus und die Änderungen nach C++11 sind auch recht überschaubar. Die Standards sind auch weitgehend rückwärtkompatibel, man kann also sehr gut inkrementel vorgehen. Man muss auch nicht alles wissen und wenn man über etwas stolpert, dass man noch nicht kennt, dann schlägt man es kurz nach und hat wieder was gelernt. Wenn jemand nur ab und zu mal etwas Code für seine Hardware schreiben muss und in Regel eher HW-Entwickelt und sich auch noch perfekt mit VHDL auskennen muss, ja der hat halt andere Werkzeuge um die er sich kümmern muss und nimmt dann verständlicher Weise eine einfachere (kleinere) Sprache oder überläßt es Anderen. > In der Realität zerfällt das in Dialekte, wegen Subsetting, die aber > zueinander inkompatibel sind. Das würde ich nicht so sehen. Leute, die am gleichen Projekt arbeiten (sollten) auch den selben Compiler verwenden und damit wären Subsets der Sprach per se kompatibel zueinander, da es immer Schnittmengen gibt. Ich würde das eher persönlichen Stil nennen. Die Zeiten, in denen es mehr Bücher über richtiges C++ als konforme C++ Compiler gab, sind aber lange vorbei (das war so Ende der 90er). > Das ist dann toll, wenn Du neue Leute in > die Firma kriegst, die einen anderen Dialekt sprechen. Die verstehen > zunächst einmal nichtmal den Code auf sprachlicher Ebene, geschweige > denn auf inhaltlicher. Längere Einarbeitung heißt höhere Kosten. Das hast Du Dir doch jetzt ausgedacht! ;-) Als freelancer sehe ich ja das eine oder andere. Was Code unlesbar macht, sind flasche Namen, flasche Abstraktionen, Redundanz etc. schlechtes Handwerk, aber nur selten die Verwendung eines bestimmten Subsets (Dialekte gibt es von C++ eigentlich nicht) von Sprachkonstrukten. Wenn Du einen eher progressiven Kollegen hast, der C99 verwendet und ausgibig Gebrauch von `const`, `restricted`, designated initializers, etc. macht, dann wird der etwas konservativere C89 Kollege doch kein Problem deswegen haben, den Code zu verstehen. Wenn der das entsprechende Konstrukt nicht kennt, dann kennt er es danach und weiter gehts... > Noch viel besser wird das, wenn eine Firma von einer anderen aufgekauft > wird, da kommt dann Freude auf. Ach, dass hast Du Dir doch auch wieder ausgedacht! ;-) Oder wie viele Übernahmen einer C++ Bude durch eine andere C++ Bude hast Du schon mitgemacht? mfg Torsten
Nop schrieb: > Torsten R. schrieb: > >> (Ich möchte nicht 250 Zeilen C-Code schreiben müssen, um damit den >> Inhalt einer im RAM liegenden Tabelle zu füllen, die nach der >> Initialisierung und wärend der ganzen Laufzeit konstant bleibt [soetwas >> gehört ins ROM]). > > Ich hab in so einem Fall diesen Prozeß beim Build auf dem Host gemacht > und dann mit xxd ein C-File erzeugt, was ich einfach ins Projekt > reincompiliert habe. Dadrin ist dann ein Array mit den nötigen > Binärdaten, das man ins ROM verfrachten kann. Ja, in C wäre der richtige Ansatz, eine domain specific language zu definieren und ein Tool zu schreiben, dass aus dieser DSL dann wieder C-Code erzeugt. Deswegen sind Tools wie Lex und Yacc ja auch so beliebt. Kann man aber auch in C++ ohne externe Tools machen.
Gerhard O. schrieb: > Was wirklich gut wäre, kollektiv ein kleines Handbuch zu erstellen über > die Do's und Don't's von C++ auf kleineren uC und GCC mit Beispielen als > gemeinsame Platform die allen zugänglich ist. Guckst Du hier: https://www.gitbook.com/book/arobenko/bare_metal_cpp/details
Sprachenlerner schrieb: > Hmmm..., wenn man immer die "ideale" Sprache nutzen will, dann kann man > wohl für jedes wechselnde Projekt auch immer die Programmiersprache > wechseln um ein Quäntchen an Perfomance, Leistungsfähigkeit, Funktionen, > Ressourcenverbrauch, etc... zu gewinnen. Ob es sinnvoll ist, alle > x-Sprachen zu kennen, das halte ich eventuell übertrieben und finde es > besser wenn man 1-2-3 Sprachen beherrscht, da aber umso besser. Oder? Ja -- wobei die betreffenden Sprachen sich durchaus auch einmal ändern können. Bisher habe ich in meinem Leben jedenfalls schon mehr Sprachen vergessen, als ich aktuell noch flüssig beherrsche. Dabei habe ich mit jeder neuen Sprache was Neues gelernt, über die Sprache hinaus. > Gern möchte ich lernen/können einen STM32 mit Touch-Display zu > programmieren (z.B. für eine Haussteuerung). Welche Sprache ist da > empfehlenswert? C, wenn Du das Erlernte weiterverwenden willst, oder C++, wenn Dir der Sinn nach ein bisschen Lernen steht. > Ebenso einen Raspberry mit Touch-Display und kleiner Visualisierung oder > größeren Aufgaben (Linux/Windows Betriebssystem?). Was nimmt man da für > eine Sprache? Entweder eine Skriptsprache wie Python, Ruby oder Perl, oder aber eine kompilierte wie C oder C++, oder ein Zwischending mit Bytecode wie Java oder C#. Meine persönliche Wahl wäre Python, für performancekritisches erweitert mit C++ und Boost.Python, für schnelle GUIs mit Tkinter/Tix beziehungsweise für hübsche GUIs wahlweise mit Qt oder über eine nette Webanwendung mit Flask, jQuery und jqWidgets oä. YMMV. > Wie sieht es auf Windows-PC aus, welche ist da die geeigneteste Sprache > um grfische Oberflächen zu programmieren? Die .NET-Sprachen wie C# und Visual Basic.NET sind die Platzhirsche, aber sie führen schnell in eine Plattformabhängigkeit. Ansonsten kannst Du für Windows mit jeder der obengenannten Sprachen eine GUI entwickeln -- YMMV. > Nun es ist nicht leicht, eventuell werden mir nun 10 Sprachen empfhlen, > aber so viele möchte ich nicht lernen. 2 oder max. 3 Sprachen, mehr > nicht, damit sollte sich alles unter einen Hut bringen lassen. Naja, C, C++, Java und C# sind wohl die Platzhirsche in der Industrie, bei dem von Dir gefragten Anwendungsspektrum (Windows und Linux, mit und ohne GUI) dürften C++ oder Java die am breitesten verwendbaren Kandidaten sein. Obendrein empfiehlt es sich, eine moderne Skriptsprache dabei zu haben, da ist Python nach meiner Wahrnehmung im Moment besonders weit vorne -- vor allem bezüglich der Unterstützung durch Bibliotheken und andere Tools.
Beitrag #5040183 wurde von einem Moderator gelöscht.
Beitrag #5040184 wurde von einem Moderator gelöscht.
Torsten R. schrieb: > Gerhard O. schrieb: >> Was wirklich gut wäre, kollektiv ein kleines Handbuch zu erstellen über >> die Do's und Don't's von C++ auf kleineren uC und GCC mit Beispielen als >> gemeinsame Platform die allen zugänglich ist. > > Guckst Du hier: > https://www.gitbook.com/book/arobenko/bare_metal_cpp/details Vielen Dank, Torsten! Das ist mir als C++ Beginner sehr nützlich. Gruß, Gerhard
Gerhard O. schrieb: > Torsten R. schrieb: >> Gerhard O. schrieb: >>> Was wirklich gut wäre, kollektiv ein kleines Handbuch zu erstellen über >>> die Do's und Don't's von C++ auf kleineren uC und GCC mit Beispielen als >>> gemeinsame Platform die allen zugänglich ist. >> >> Guckst Du hier: >> https://www.gitbook.com/book/arobenko/bare_metal_cpp/details > > Vielen Dank, Torsten! > > Das ist mir als C++ Beginner sehr nützlich. Genau dafür hatte ich diesen Thread mal begonnen: Beitrag "Informationen zu C vs C++ / aka Futter für die Diskussion" Da könnte man mal was nachlesen ...
Wilhelm M. schrieb: > Da könnte man mal was nachlesen ... Vielen Dank auch Dir, Wilhelm. Den Thread kannte ich noch gar nicht. Gruß, Gerhard
Beitrag #5040320 wurde von einem Moderator gelöscht.
Beitrag #5040341 wurde von einem Moderator gelöscht.
Torsten R. schrieb: > Das ist eigentlich überhaupt kein Problem, wenn man das Hauptberuflich > macht. Naja, wenn da das hauptberuflich nutzt dann stellt sich doch die Frage des Threadthemas nicht, oder? > Guckst Du hier: > https://www.gitbook.com/book/arobenko/bare_metal_cpp/details Danke für das Buch, interessante Einleitung (mehr würde ich eh nicht verstehen) da auf mich ich Seite 6 Absatz 2 zutrifft: >> "...is that software in significant number (if not majority) >> of projects gets written by hardware developers" ... >> "The “C” programming language is a natural choice for them" Wenn ich aber ne Frage stellen dürfte (so aus den Tal der Ahnungslosen) Da ist auf den ersten Seiten davon die Rede >> "that templates are dangerous because of executable code bloating" Was dann auch nicht bestritten sondern bestenfalls relativiert wird und weiter unten steht dann dass eben genau diese Templates ja der wichtigste Grund für µC-C++ wären "because of code reuse" Wie gesagt ich hab null Ahnung von C++ aber ist das nicht widersprüchlich? Zum Thema code reuse hab ich noch ne Frage: Bei "C" "reuse" ich u.a. USB mass storage oder TFT driver etc ständig da es schlicht libs sind. Was ist da in C++ groß anders?
X4U schrieb: > Wie gesagt ich hab null Ahnung von C++ aber ist das nicht > widersprüchlich? Nein! Das ist die ReineWahrheit. z.B. eine Funktion, soll irgendeinen Datentype über die Serielle raus schicken. Der C Programmierer schreibt für jeden Datentype eine eigene Funktion. Alle den gleichen Namen, aber unterschiedliche Signaturen. Der C++ Programmierer schreibt eine Template-Funktion. Der Compiler macht in beiden Fällen das gleiche draus. In C werden überflüssige Funktionen (in der Regel) weg optimiert In C++ erzeugt der Compiler automatisch die benötigten Varianten. Templates können also den Code aufblähen, ohne dass es unmittelbar im Code ersichtlich ist.
Arduino F. schrieb: > X4U schrieb: >> Wie gesagt ich hab null Ahnung von C++ aber ist das nicht >> widersprüchlich? > > Nein! > Das ist die ReineWahrheit. > > z.B. eine Funktion, soll irgendeinen Datentype über die Serielle raus > schicken. > > Der C Programmierer schreibt für jeden Datentype eine eigene Funktion. > Alle den gleichen Namen, aber unterschiedliche Signaturen. Nein, da C keine Funktionsüberladung besitzt.
Arduino F. schrieb: > Der C++ Programmierer schreibt eine Template-Funktion. > Der Compiler macht in beiden Fällen das gleiche draus. Das könnte sein ... > In C werden überflüssige Funktionen (in der Regel) weg optimiert Falls sie in einer Bibliothek sind, werden sie erst gar nicht dazu gebunden. > In C++ erzeugt der Compiler automatisch die benötigten Varianten. Ja, und nur die. > Templates können also den Code aufblähen, ohne dass es unmittelbar im > Code ersichtlich ist. Das sehe ich einem Stück Code aus einer Bibliothek auch nicht an.
Arduino F. schrieb: > Der C Programmierer schreibt für jeden Datentype eine eigene Funktion. > Alle den gleichen Namen, aber unterschiedliche Signaturen. Also meine Wenigkeit nutzt in C sprintf und schiebt den String raus. Da braucht es gar keine eigene Funktion. Wenn man selbsterklärende Variablennamen hat wird auch sofort klar was da passiert. Insofern hinkt das Beispiel etwas, aber das mit den Templates verstehe ich. Danke für die Erklärung
> Vincent Hamp (vinci) > Eigentlich ist kein einziger Chiphersteller daran interessiert vernünftige Bibliotheken anzubieten. Bibliotheken bringen kein Geld und verkaufen keine Hardware. Was fuer eine Bibliothek denn ? Die Peripherien sind nun mal verschieden und bieten verschiedene Moeglichkeiten. Es gibt Leute, die sind mit einem PWM zufrieden, Andere, die wollen waehrend des 0-Zustandes schnell den ADC anwerfen und auslesen. Andere wollen ein PWM dithering haben. Deswegen schreibt man sich die gewuenschte Funktion einmal und verwendet sie wieder.
Wilhelm M. schrieb: > Nein, da C keine Funktionsüberladung besitzt. OK, dann behaupte ich ab jetzt das Gegenteil.
Arduino F. schrieb: > X4U schrieb: >> Wie gesagt ich hab null Ahnung von C++ aber ist das nicht >> widersprüchlich? > > Nein! > Das ist die ReineWahrheit. Die Wahrheit liegt wie so oft irgendwo dazwischen. "Templates erzeugen code bloat." [X] falsch "Tamples erzeugen keinen code bloat." [X] falsch "Falsch angewandt erzeugen Templates code bloat." [X] richtig "Richtig angewandt erzeugen Templates keinen code bloat." [X] richtig Folgendes simple Beispiel erzeugt unter gcc-7.1.0 den selben Code:
1 | // Template print
|
2 | template<size_t I> |
3 | static void template_print(const char (&str)[I]) |
4 | {
|
5 | printf("%s\n", str); |
6 | }
|
7 | |
8 | // Non template print
|
9 | static void non_template_print(const char* str) |
10 | {
|
11 | printf("%s\n", str); |
12 | }
|
13 | |
14 | // Print different versions...
|
15 | template_print("SzKL4yLe791xmL31XA"); |
16 | template_print("SzKL4yLe791xmL31XA,"); |
17 | template_print("SzKL4yLe791xmL31XA,0"); |
18 | non_template_print("SzKL4yLe791xmL31XA"); |
19 | non_template_print("SzKL4yLe791xmL31XA,"); |
20 | non_template_print("SzKL4yLe791xmL31XA,0"); |
Das mag jetzt ein dummes Beispiel sein, zeigt aber zumindest, dass Templates nicht automatisch Unmengen an Flash fressen.
X4U schrieb: > Naja, wenn da das hauptberuflich nutzt dann stellt sich doch die Frage > des Threadthemas nicht, oder? Äh, ich habe beim OP keine Einschränlung auf Nebenberuflichkeit gesehen. Für mich ist C++ die beste Wahl wenn es um die Entwicklung von Firmware geht (solange es für den Controlller einen C++ Compiler gibt). > Danke für das Buch, interessante Einleitung (mehr würde ich eh nicht > verstehen) da auf mich ich Seite 6 Absatz 2 zutrifft: > >>> "...is that software in significant number (if not majority) >>> of projects gets written by hardware developers" ... >>> "The “C” programming language is a natural choice for them" Hatte ich weiter oben sinngemß, ähnlich geschrieben. Ich bin aber auch der Meinung, dass Hardware-Entwickler Hardware entwickeln sollten und SW-Entwickler SW. Sicher, dass geht nicht immer, aber es ist sinnvoll. > Wenn ich aber ne Frage stellen dürfte (so aus den Tal der Ahnungslosen) > > Da ist auf den ersten Seiten davon die Rede >>> "that templates are dangerous because of executable code bloating" > > Was dann auch nicht bestritten sondern bestenfalls relativiert wird und > weiter unten steht dann dass eben genau diese Templates ja der > wichtigste Grund für µC-C++ wären "because of code reuse" Templates haben mehrere Anwendungen: Eine Anwendung ist dem von Makros in C recht ähnlich. Typsicherer und kann bei entsprechend häufiger Instanziierung mit verschiedenen Typen dazu führen, dass identischer Code mehrfach im Binary landet (z.B. wenn die Typen sehr ähnlich sind, wie Zeiger). Das Problem kann man auch mit Makros haben, oder mit Copy/Paste. Das muss aber nicht immer ein Problem sein: bevor ich den gleichen Code für unterschiedliche Datentypen in der Codebasis habe, habe ich Ihn lieber einmal als template, auch wenn ich dann mehrer unterschiedliche Instanziierungen im Binary habe. Wenn es ein Problem ist, dann ist die Lösung häufig die, die auch in C verwendet wird. Sprich void* Siehe auch Diskusion std::sort() / qsort() hier im thread. > Wie gesagt ich hab null Ahnung von C++ aber ist das nicht > widersprüchlich? Nein, ist es nicht. Bei jedem Werkzeug muss man die Vor- und Nachteile abwägen. Um die Wahl bei den Werkzeugen zu haben, muss ich sie kennen. Immer dieses: Ich hatte damit (Diamant, Code-Bloat, Memory Leak...) mal ein Problem, also ist es böse und gehört verbant ist doch kontraproduktiv. Aus Fehlern sollte man einfach lernen. > Zum Thema code reuse hab ich noch ne Frage: Bei "C" "reuse" ich u.a. > USB mass storage oder TFT driver etc ständig da es schlicht libs sind. > Was ist da in C++ groß anders? C++ hat einfach ein paar mehr Möglichkeiten vorgefertigte Lösungen anzubieten: Wenn ich in C eine Library habe und ich möchte ohne overhead callbacks des Benutzers von der Library heraus aurufen, dann passiert das in C in der Regel mit weak symbols. Das sind aber globale Namen, sprich sobald ich mehr als einen USB Anschluss implementieren möchte, müssen diese Namen unterschiedlich sein. Wenn ich einen Satz an Funktionen implementieren muss, dann hat die Library auch keine Möglichkeit, mir eine Fehlermeldung zu geben, wenn ich als Nutzer eine Funktion vergessen habe. In C++ verwendet man an der Stelle compile time polymorphism (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). In C++ kann man Libraries auch besser Konfigurieren, sodass ungenutzter Code und Daten nicht im finalen Binary auftauchen. Das wesentliche Mittel in C dazu sind Makros. Mit C++ kann man deutlich einfacher interne Domain Specific Languages bauen. Dann beschreibst Du als Nutzer einer Libray nur noch das zu lösende Problem und Library implementiert eine Lösung.
Arduino F. schrieb: > Templates können also den Code aufblähen, ohne dass es unmittelbar im > Code ersichtlich ist. Templates können den Code aber auch oft kleiner und schneller machen, weil man nicht mehr (s.a. oben qsort()) eine Funktion hat, die mit allen DT oder z.B. Array-Längen umgehen können muss, sondern man kann mit Hilfe von z.B. traits den Code eben besser anpassen.
Vincent Hamp (vinci) > Eigentlich ist kein einziger Chiphersteller daran interessiert > vernünftige Bibliotheken anzubieten. Bibliotheken bringen kein Geld und > verkaufen keine Hardware. Natürlich nicht, ein Chiphersteller stellt Chips her. Es gibt aber Firmen wie Keil, IAR etc die sehr produktive Toolchains haben, mit sehr guten libs. Nur kosten die halt Geld. Torsten R. schrieb: > sobald ich mehr als einen USB Anschluss implementieren möchte, müssen > diese Namen unterschiedlich sein. Sind Sie ja auch, was imho Sinn macht. Wo ist der unterschied zwischen (mal ganz einfach) write_uart_3(SomeStuff); und Tabellen? > In C++ verwendet man an der Stelle compile time polymorphism Das mag ja sein, aber irgendjemand muss dem wie auch immer gearteten Compiler erzählt werden wo a.) die Schnittstellen sind (macht bei C die Lib) und b.) welche du gerade Nutzen willst (muss man leider selber machen). > Mit C++ kann man deutlich einfacher interne Domain Specific Languages > bauen. Dann beschreibst Du als Nutzer einer Libray nur noch das zu > lösende Problem und Library implementiert eine Lösung. Danke für die ausführliche Erklärung. Aber sowas ist ehrlich gesagt das letzte was ich persönlich möchte. Das ist aber sicher sinnvoll wenn man nur Firmware für einen bestimmten Produktbereich macht. Für mich gilt so wenig Abstraktionslayer wie möglich, aber das ist natürlich sehr spezifisch.
Wilhelm M. schrieb: >> Templates können also den Code aufblähen, ohne dass es unmittelbar im >> Code ersichtlich ist. > > Das sehe ich einem Stück Code aus einer Bibliothek auch nicht an. Ein Bild sagt mehr als 1000 Worte
Torsten R. schrieb: > Äh, ich habe beim OP keine Einschränlung auf Nebenberuflichkeit gesehen. > Für mich ist C++ die beste Wahl wenn es um die Entwicklung von Firmware > geht (solange es für den Controlller einen C++ Compiler gibt). > [...] > Mit C++ kann man deutlich einfacher interne Domain Specific Languages > bauen. Dann beschreibst Du als Nutzer einer Libray nur noch das zu > lösende Problem und Library implementiert eine Lösung. Genau darum geht es doch auch. Ich stimme dem Torsten hier zu. Wenn ich eine Plattform verwende auf der ich besser wartbaren und weiterverwendbaren Code schreiben kann, der dann obendrein auch noch angenehmer zu entwickeln ist, dann mache ich das auch so. Wenn ich mich auf etwas anderes einlassen muss, weil es so günstiger ist, dann mache ich das natürlich auch. Also nur um die Lieblingsentwicklungsumgebung zu verwenden wäre es z.B. doof wenn ein viel teurerer und energiehungrigerer Controller eingesetzt wird. Wobei ich das wiederum für private Projekte auf jeden Fall so machen würde ;-)).
X4U schrieb: > Wilhelm M. schrieb: >>> Templates können also den Code aufblähen, ohne dass es unmittelbar im >>> Code ersichtlich ist. >> >> Das sehe ich einem Stück Code aus einer Bibliothek auch nicht an. > > Ein Bild sagt mehr als 1000 Worte Und? Das kannste für templates doch auch machen ...
Zurück zum Kern der eigentlichen Frage: Unbedingt auch mal LunaAVR anschauen ! http://avr.myluna.de http://avr.myluna.de/doku.php?id=de:luna-commands
X4U schrieb: > Torsten R. schrieb: >> sobald ich mehr als einen USB Anschluss implementieren möchte, müssen >> diese Namen unterschiedlich sein. > > Sind Sie ja auch, was imho Sinn macht. > Wo ist der unterschied zwischen (mal ganz einfach) > > write_uart_3(SomeStuff); > > und Tabellen? Ich sehe keine Tabellen. Der Unterschied sind global eindeutige Symbole in C und recht lokale Symbole in C++:
1 | void HAL_UART4_ReadHandler(void* input) |
2 | { |
3 | handle_uart_input(input, first_compass); |
4 | } |
5 | |
6 | void HAL_UART4_ErrorHandler() |
7 | { |
8 | handle_uart_error(first_compass); |
9 | } |
10 | |
11 | void HAL_UART3_ReadHandler() |
12 | { |
13 | handle_uart_input(input, second_compass); |
14 | } |
15 | |
16 | void HAL_UART3_ErrorHandler() |
17 | { |
18 | handle_uart_error(second_compass); |
19 | } |
vs.
1 | compass< UART3 > first_compass; |
2 | compass< UART4 > second_compass; |
> Für mich gilt so wenig Abstraktionslayer wie möglich, aber das ist > natürlich sehr spezifisch. Dann nimm Assembler!
Wilhelm M. schrieb: > Was C ggf. interessant machen könnte, sind nicht-standardisierte > Erweiterungen wie memory-sections __flash oder auch saturierende arith. > Typen und FixedPoint. > > Aber: das ist eigentlich wieder ein Argument für C++, denn die o.g. > Dinge hat man schnell in C++ realisiert bzw. nimmt eine entsprechende > Bibliothek und hat damit wieder vollständig konformen Code. Also der Nachteil, dass C++ kein __flash Unterstützt, ist ein Vorteil von C++? Tolles Argument. Bis jetzt hab ich auch keine Überzeugende Implementierung von __flash in C++ gesehen, alles was C++ machen kann ist nicht-standard Erweiterungen wie Attribut progmem und Inline-Assembler (via pgm_read_xxx) irgendwie zu verstecken. Und ja, irgendwann hab ich mal 100+ Zeilen C++ von dir gesehen, die das alles "ganz einfach" machen. Irgendwie hab ich den Eindruck, du hast ein bissl den Realitätsbezug und die Bodenhaftung verloren. Ich kann leidlich C++, aber ein Framework, das __flash abbildet und mit Strings, Array, eigenen Typen etc. arbeitet würd ich ehrlich gesagt nicht hinbekommen mit all den variadischen Templates (die man im Gegensatz zu Makros noch nichtmal debuggen kann) und wer weiß was alles. Und gleiche Performance ist nochmal ein ganz anderes Thema. 99.99% verwenden wohl einfach progmem + pgm_read_xxx und das war's. Oder gleich µC wo man solche Hacks nicht braucht. Aber alleine, dass C++ nicht in der Lage ist, einen Qualifier zu modellieren oder zu implementieren, Lässt für mich schon Zweifel an der "Mächtigkeit" der Sprache aufkommen. Gerade im Embedded-Bereich sind Qualifier wie __flash, __near, oder __far ja nicht unüblich, aber C++ ist auf dem Auge blind...
:
Bearbeitet durch User
Torsten R. schrieb: > Ich sehe keine Tabellen. Der Unterschied sind global eindeutige Symbole > in C und recht lokale Symbole in C++: ... Danke für die Erklärung. Zum Verständnis meinerseits: > compass< UART3 > first_compass; wo ist da die Fehlerbehandlung. > void HAL_UART4_ReadHandler(void* input) > { > handle_uart_input(input, first_compass); > } > ... > void HAL_UART3_ErrorHandler() > { > handle_uart_error(second_compass); > } Bei mir wäre der ErrorHandler Teil der Funktion.
1 | if (HAL_UART4_ReadHandler == 0) { MachWas} |
2 | else { Handle the Fu**ingError} ** = no PointerToPointer |
Da kann man jetzt noch einen weiteren layer rüberpacken damit das zu
einer function wird.
Bitte nicht in falschen Hals kriegen, wenn C++ was für mich ist bin ich
ab morgen am lernen, ich möchte das nur verstehen.
> Dann nimm Assembler!
;-)
Beitrag #5040519 wurde von einem Moderator gelöscht.
Beitrag #5040529 wurde von einem Moderator gelöscht.
Beitrag #5040530 wurde von einem Moderator gelöscht.
X4U schrieb: > Danke für die Erklärung. Zum Verständnis meinerseits: > >> compass< UART3 > first_compass; > > wo ist da die Fehlerbehandlung.
1 | template < typename Uart > |
2 | void compass< Uart >::error_handler() |
3 | { |
4 | set_error_flag(); // or what ever, same code for every compass connect |
5 | } |
> Bei mir wäre der ErrorHandler Teil der Funktion. > >
1 | if (HAL_UART4_ReadHandler == 0) { MachWas} |
2 | > else { Handle the Fu**ingError} ** = no PointerToPointer |
Deine Ausgangs-Frage drehte sich um Code-Reuse und was C++ für uns tun kann. Dass dein Code so nicht ein zweites mal genutzt werden kann, sollte klar sein. > Da kann man jetzt noch einen weiteren layer rüberpacken damit das zu > einer function wird. Dass wollte ich mit meinem C-Skelett von oben so andeuten und aufzeigen, dass man in C++ als Nutzer eine Library deutlich einfacher SW-Teile mit einander verbinden kann. >> Dann nimm Assembler! > ;-) Das war ernst gemeint. Entweder Du möchtest "so wenig Abstraktionslayer wie möglich", dann ist Assembler oder sogar Maschinencode das konkreteste, was Du haben kannst, oder die Aussage degeneriert zu einem: "Ich bin mit den Abstraktionen, die mir C bietet zufrieden". Was auch nicht schlimm ist, dann sollte man aber auch nichts anderes behaupten.
Johann L. schrieb: > Und ja, irgendwann hab ich mal 100+ Zeilen C++ von dir gesehen, die das > alles "ganz einfach" machen. Irgendwie hab ich den Eindruck, du hast > ein bissl den Realitätsbezug und die Bodenhaftung verloren. Die 100+ Zeilen sind 23 Zeilen ... > Ich kann leidlich C++, aber ein Framework, das __flash abbildet und mit > Strings, Array, eigenen Typen etc. arbeitet würd ich ehrlich gesagt > nicht hinbekommen mit all den variadischen Templates (die man im > Gegensatz zu Makros noch nichtmal debuggen kann) und wer weiß was alles. Gut, wenn Du es nicht weißt, ist das natürlich erstmal nicht schlimm, solange Du nicht versuchst mit zu reden ... > Und gleiche Performance ist nochmal ein ganz anderes Thema. Und schon wieder dieses Un-Argument. > Aber alleine, dass C++ nicht in der Lage ist, einen Qualifier zu > modellieren oder zu implementieren, Manche Dinge sind eben anders, weil sie anders sein müssen. Siehe auch die Behandlungs von unions (active member). > Lässt für mich schon Zweifel an der > "Mächtigkeit" der Sprache aufkommen. Gerade im Embedded-Bereich sind > Qualifier wie __flash, __near, oder __far ja nicht unüblich, aber C++ > ist auf dem Auge blind... Wie Du ja gesehen hast, geht es trotzdem ...
Beitrag #5040549 wurde von einem Moderator gelöscht.
Johann L. schrieb: > Bis jetzt hab ich auch keine Überzeugende Implementierung von __flash in > C++ gesehen, alles was C++ machen kann ist nicht-standard > Erweiterungen wie Attribut progmem und Inline-Assembler (via > pgm_read_xxx) irgendwie zu verstecken. Nur zur Info __flash ist nicht Bestandteil von C sondern nur eine compilerspezifische Erweiterung des GCCs. Eigentor. Johann L. schrieb: > Aber alleine, dass C++ nicht in der Lage ist, einen Qualifier zu > modellieren oder zu implementieren, Lässt für mich schon Zweifel an der > "Mächtigkeit" der Sprache aufkommen. Gerade im Embedded-Bereich sind > Qualifier wie __flash, __near, oder __far ja nicht unüblich, aber C++ > ist auf dem Auge blind... Ich frage mich wie du dann überhaupt C in Betracht ziehen kannst, eine Sprache die nicht mal sowas wie echte Konstanten kennt (const wohl eher nicht...).
Beitrag #5040586 wurde von einem Moderator gelöscht.
Torsten R. schrieb: >> Bei mir wäre der ErrorHandler Teil der Funktion. >> >>if (HAL_UART4_ReadHandler == 0) { MachWas} >> else { Handle the Fu**ingError} ** = no PointerToPointer > Deine Ausgangs-Frage drehte sich um Code-Reuse und was C++ für uns tun > kann. Dass dein Code so nicht ein zweites mal genutzt werden kann, > sollte klar sein. Sorry für die naive Frage im voraus, warum nicht? Den kann ich doch genauso einfach cut and pasten. >>> Dann nimm Assembler! >> ;-) > > Das war ernst gemeint. Entweder Du möchtest "so wenig Abstraktionslayer > wie möglich", dann ist Assembler oder sogar Maschinencode das > konkreteste, was Du haben kannst, Ist es eben nicht da Assembler und Maschinencode auch abstrakte sind. Mit DIL Schaltern die Patterns auf die Datenleitungen legen wäre noch weniger abstrakt. > "Ich bin mit den Abstraktionen, die mir C bietet zufrieden". Bei C von zufrieden zu reden ist schon schwierig. Es ist halt ein Kompromiss. Man ist dicht genug auf der Hardware, hat aber eine Art Hochsprache besser evtl. mit "universeller Makroassembler" definiert.
X4U schrieb: > Torsten R. schrieb: >> Deine Ausgangs-Frage drehte sich um Code-Reuse und was C++ für uns tun >> kann. Dass dein Code so nicht ein zweites mal genutzt werden kann, >> sollte klar sein. > > Sorry für die naive Frage im voraus, warum nicht? Den kann ich doch > genauso einfach cut and pasten. Weil Du selbst bei "Copy & Past"-Reuse (wobei meine Definition von Code-Reuse etwas anders wäre), die "4" ändern müsstest.
Da hier ja schon mehrfach über den Einsatz von C++ in der Industrie diskutiert wurde wollte ich nochmal (ganz wertfrei) die Compilerunterstützung als Argument einwerfen, warum C++ derzeit noch nicht so weit verbreitet ist. Klar gibt es den GCC und Clang und ich bin der Meinung das dies beides sehr gute Compiler sind aber wenn ich mich bei den "professionellen" Tools wie Keil oder IAR umschaue, so gibt es da derzeit maximal C++03, womit einige (mMn überaus nützliche) Features wie etwa constexpr unter den Tisch fallen. Ich weiß nicht genau wie die Lage bei Microchip oder anderen Compilerherstellern wie z.B. GreenHill ist aber ich vermute sie ist ähnlich. Natürlich steht die Welt nicht still, sondern dreht sich weiter und Keil hat daher ja auch seine künftigen Compiler komplett auf Clang-Basis umgestellt und wird damit künftig auch C++14 unterstützen. Bisher gibt es das aber nur für Cortex-A und der für Cortex-M befindet sich noch in der Beta-Phase und selbst wenn der dann mal endgültig released wird, wird einige Zeit ins Land gehen, bis die neuen Features von der großen Masse angenommen werden.
Beitrag #5040612 wurde von einem Moderator gelöscht.
Beitrag #5040615 wurde von einem Moderator gelöscht.
Beitrag #5040618 wurde von einem Moderator gelöscht.
PeterPan schrieb: > __flash ist nicht Bestandteil von C sondern nur eine compilerspezifische > Erweiterung des GCCs. Eigentor. Namend memory spaces sind Bestandteil eines Standardvorschlags für Embedded C. Johann wollte darauf hinaus, dass dieser Vorschlag jedoch auf einem standardmäßig bei C vorhandenen Feature basiert, den type qualifiers, die es bei C++ nicht gibt.
Torsten R. schrieb: >>> Dann nimm Assembler! >> ;-) > > Das war ernst gemeint. Entweder Du möchtest "so wenig Abstraktionslayer > wie möglich", dann ist Assembler oder sogar Maschinencode das > konkreteste, was Du haben kannst Ich finde es nicht fair, C in die Nähe von Assembler zu rücken. C abstrahiert den Befehlssatz des Prozessors. Auch wenn beide ähnlich performant sind, und bei der Beschreibung der Register ähnlich aussehen, so ist der Unterschied von C zu Assembler ein Quantensprung. Noch weitaus größer als der zu C++. C++ ist eigentlich (überspitzt gesagt) das, was es zu Anfang war: Eine Metaprogrammiersprache für C, die alle guten Sprachkonzepte früher oder später in sich vereint. Nur das die C-Code Generierung heute nicht mehr benötigt wird.
Beitrag #5040653 wurde von einem Moderator gelöscht.
Achim.S schrieb: > Ich finde es nicht fair, C in die Nähe von Assembler zu rücken. Ach Meno! Gewöhnt euch doch mal an, Sätze im Kontext zu lesen und nicht immer irgend welche Halbsätze zu lesen und dann darauf frei von jedem Kontext zu antworten!!! Hier geht es los: >> Für mich gilt so wenig Abstraktionslayer wie möglich, aber das ist >> natürlich sehr spezifisch. > Dann nimm Assembler! Wo habe ich jetzt C in die Nähe von Assembler gerückt? X4U möchte so wenig Abstraktion, wie möglich. Also habe ich ihm Assembler nahe gelegt. Wie Du selbst schreibst: > C abstrahiert den Befehlssatz des Prozessors. Weniger abstrakt wäre dann direkt mit dem Befehlsatz des Prozessors zu arbeiten. Das wäre dann Assembler oder Maschinencode. Ich verabschiede mich jetzt aus der Diskusion, die dreht sich doch nur noch im Kreis.
Ich wette es gibt nicht genug Argumente gegen C++ um auf 1000 postings zu kommen. Denn niemand kennt die Sprache so gut, als dass er so viel dazu schreiben könnte, auch nicht die Community hier. Vielleicht sollten wir mal Bjarne Stroustrup einladen.
Jörg W. schrieb: > PeterPan schrieb: >> __flash ist nicht Bestandteil von C sondern nur eine compilerspezifische >> Erweiterung des GCCs. Eigentor. > > Namend memory spaces sind Bestandteil eines Standardvorschlags für > Embedded C. Johann wollte darauf hinaus, dass dieser Vorschlag jedoch > auf einem standardmäßig bei C vorhandenen Feature basiert, den type > qualifiers, die es bei C++ nicht gibt. Ah ich verstehe, wusste ich noch gar nicht. Dann nehm ichs Eigentor zurück. Auf dem AVR mach kaum noch was und auf nem ARM Cortex muss man sich sowas nicht antun, da ist der ROM im gleichen Adressraum.
Ich hab damals von meinen Amigakumpels vorgeworfen bekommen ich sei ein "lamer skripter" weil ich auf einmal auch einen PC hatte auf dem ich mit Turbo-C gecodet hatte wo ich doch so gut den 68k-asm konnte. Ist irgendwie beruhigend das 25 Jahre später noch die gleiche Art von Diskussion gepflegt wird. :-D
Jörg W. schrieb: >> PeterPan schrieb: >>> __flash ist nicht Bestandteil von C sondern nur eine compilerspezifische >>> Erweiterung des GCCs. Eigentor. >> >> Namend memory spaces sind Bestandteil eines Standardvorschlags für >> Embedded C. Johann wollte darauf hinaus, dass dieser Vorschlag jedoch >> auf einem standardmäßig bei C vorhandenen Feature basiert, den type >> qualifiers, die es bei C++ nicht gibt. Natürlich gibt es type-qualifier in C++: const, volatile, mutable. Nur __flash, __flash1, ... als spezieller qualifier für named-address-spaces eben nicht, weil das eben non-standard Erweiterungen sind (erster TR aus 2003).
Torsten R. schrieb: > X4U möchte so > wenig Abstraktion, wie möglich. Also habe ich ihm Assembler nahe gelegt. Danke für den Tipp, aber Assembler ist nun mal maschinenspezifisch. Dadurch wird die Abstraktion wieder größer da du mit mehreren Sprachen und Architekturen hantierst. Davon ab gibt es keine Libs in Assembler. > Ich verabschiede mich jetzt aus der Diskusion, die dreht sich doch nur > noch im Kreis. Dito, ist eh sinnlos weil jeder so oder so macht was er will. Torsten R. schrieb: > Weil Du selbst bei "Copy & Past"-Reuse (wobei meine Definition von > Code-Reuse etwas anders wäre) klar, es geht für mich darum das zu versehen also daher der simple Kontext > , die "4" ändern müsstest. Bitte nicht falsch verstehen, ich wechsle sofort zu C++ wenn ich das verstehe und für mich sinnvoll ist. So toll C ist, produktiv ist dieses Assemblersteno wirklich nicht. Nun die Frage: Woher weiß denn dein C++ das die Schnittstelle 4 jetzt eine andere ist? Also etwas das über
1 | #define compass1 = IrgendNeSerielle
|
hinausgeht?
Wilhelm M. schrieb: > Nur __flash, __flash1, ... als spezieller qualifier für > named-address-spaces eben nicht, weil das eben non-standard > Erweiterungen sind … die man dort offenbar aber nicht haben will. Ansonsten hätte ja nichts dagegen gesprochen, dass Johann sie auch für C++ aktiviert. Ist ja nicht so, dass sie einfach so von sich aus im C-Compiler aufgetaucht wären.
Beitrag #5040760 wurde von einem Moderator gelöscht.
Beitrag #5040775 wurde von einem Moderator gelöscht.
Beitrag #5040789 wurde von einem Moderator gelöscht.
Beitrag #5040807 wurde von einem Moderator gelöscht.
Beitrag #5040818 wurde von einem Moderator gelöscht.
Beitrag #5040825 wurde von einem Moderator gelöscht.
X4U schrieb: > Bei C von zufrieden zu reden ist schon schwierig. Es ist halt ein > Kompromiss. Man ist dicht genug auf der Hardware, hat aber eine Art > Hochsprache besser evtl. mit "universeller Makroassembler" definiert. Exakt. Die Dosis macht das Gift. Und außerdem ist einer der Vorteile von C, daß es einen Haufen Abstraktionen nicht bietet und man, wie Torvalds schon anmerkte, damit auch Leute draußen hält, die sich mehr daran hochziehen als an der eigentlichen Aufgabe. Ich finde, dieser Thread bestätigt Torvalds' Rant recht beeindruckend. PeterPan schrieb: > auf nem ARM Cortex muss man > sich sowas nicht antun, da ist der ROM im gleichen Adressraum. Es kann aber verschiedene Sorten disjunktes RAM geben. SRAM, CCM, Backup-RAM. Da muß man schon entscheiden, welche Variablen wohin gehen sollen.
Beitrag #5040853 wurde von einem Moderator gelöscht.
Beitrag #5040879 wurde von einem Moderator gelöscht.
Nop schrieb: > X4U schrieb: > >> Bei C von zufrieden zu reden ist schon schwierig. Es ist halt ein >> Kompromiss. Man ist dicht genug auf der Hardware, hat aber eine Art >> Hochsprache besser evtl. mit "universeller Makroassembler" definiert. > > Exakt. Die Dosis macht das Gift. > > Und außerdem ist einer der Vorteile von C, daß es einen Haufen > Abstraktionen nicht bietet und man, wie Torvalds schon anmerkte, damit > auch Leute draußen hält, die sich mehr daran hochziehen als an der > eigentlichen Aufgabe. Ich finde, dieser Thread bestätigt Torvalds' Rant > recht beeindruckend. Was willst du eigentlich ständig mit Torvalds? Gibt es überhaupt irgendwas auf der Welt worüber Linus keinen Rant starten kann? Das er Linux initiiert hat und ein führender Entwickler ist, schließt nicht aus, dass er Schwachsinn über C++ schreiben kann. Nop schrieb: > PeterPan schrieb: >> auf nem ARM Cortex muss man >> sich sowas nicht antun, da ist der ROM im gleichen Adressraum. > > Es kann aber verschiedene Sorten disjunktes RAM geben. SRAM, CCM, > Backup-RAM. Da muß man schon entscheiden, welche Variablen wohin gehen > sollen. Das regle ich über mein Linkerscript und den dazugehörigen Sections. Diese ganze Dogmatik erinnert mich an einen Labview Anhänger, der mir weiß machen wollte, dass Grafische Programmierung generell den Textsprachen überlegen ist. Dass C Programmieren das schlimmste auf der sei, dass man C ja sowas von gar nicht debuggen kann und allerhand anderen Schwachsinn. Wobei er nie mit C programmiert hat oder mit irgendeiner anderen textbasierte Programmiersprache...
Beitrag #5040893 wurde von einem Moderator gelöscht.
Nachdem wir nun endlich geklärt haben, dass C in allen Belangen besser ist würde mich interessieren, wie man hier im Forum eigentlich zu Rust und Konsorten steht? Rust bietet ja quasi die Möglichkeit zur Abstraktion ohne eigentliche Klassen? Ich würde jemanden bitten mir hier meine Meinung zu justieren, ich weiß nämlich nicht ob ich Rust jetzt schlecht finden muss?
Vincent H. schrieb: > Nachdem wir nun endlich geklärt haben, dass C in allen Belangen besser > ist würde mich interessieren, wie man hier im Forum eigentlich zu Rust > und Konsorten steht? > > Rust bietet ja quasi die Möglichkeit zur Abstraktion ohne eigentliche > Klassen? Ich würde jemanden bitten mir hier meine Meinung zu justieren, > ich weiß nämlich nicht ob ich Rust jetzt schlecht finden muss? Du mußt. Es ist !C.
Jörg W. schrieb: > Wilhelm M. schrieb: >> Nur __flash, __flash1, ... als spezieller qualifier für >> named-address-spaces eben nicht, weil das eben non-standard >> Erweiterungen sind > > … die man dort offenbar aber nicht haben will. Ansonsten hätte ja > nichts dagegen gesprochen, dass Johann sie auch für C++ aktiviert. Da ist nix mit "aktivieren". Qualifier sind eine Erweiterung des C-Fronts und des GCC Middle-Ends, und das AVR-Backend implementiert einige extra Qualifier. Aber das C++-Front anzupassen (geschweige denn die Spez dahingehend zu erweitern), ist noch mal ne gan zandere Geschichte. Wenn man sich alle Abartigkeiten von C++ zusammen vorstellt, bekommt man ne Idee, das sowas in einem Compiler FrontEnd nicht so ganz trivial umzusetzen (und zu testen) ist. Was die Spez angeht: > "WG21 has been burnt by volatile" hieß es mal in einem ML-Thread zu Thema: WG21 ist, was Qualifier angeht, ein gebranntes Kind und wird den Teufel tun, Qualifier nochmals anzufassen. Zumal ISO/IEC DTR 18037 auch "Embedded-C" heißt, und das ist deutlich unter dem Radar des momentanen Entwicklungsfokus, wo es z.B. darum geht, wie man ISAs mit SIMD mit 4x double effizient parallelisiert... Dabei geht DTR 18037 weit über das vom GCC angebotene Qualifier-Interface hinaus, indem es sogar User-defined Qualifier einführt (nicht von GCC implementier), die ermöglichen, neue Qualifier auf Applikationsebene einzuführen. Aber wie gesagt: Das Radar... Außerdem greift das non-standard Argument auch nicht wirklich. Oft waren Spracherweiterungen wie GNU-C oder GNU-C++ Vorreiter von Erweiterungen des Standards, die Praxistauglichkeit demonstrierten. Erweiterungen am grünen Tisch zu entwerfen ist nicht immer so glücklich, wie die Diskussion um atomic zeigt, und ein großer Teil von Embedded-C kann man getrost in die Tonne treten da unbrauchbar (obwohl sie von einem WG14 Mitglied stammen!). Inzwischen gibt es aber eher ein Henne-Ei Problem: Die Compilerbauer wollen nicht mehr gerne nichtstandard Erweiterungen einbauen, weil die oft problematisch sind (Kompatibilität, Wartung, Stabilität), und was in den Standard zu bringen "Out of thin Air" ist noch aussichtsloser. Ich verstehe aber immer noch nicht, warum __flash in Embedded-C ein Argument gegen C und für C++ sein soll.
Vincent H. schrieb: > Nachdem wir nun endlich geklärt haben, dass C in allen Belangen besser > ist würde mich interessieren, wie man hier im Forum eigentlich zu Rust > und Konsorten steht? Um Gottes Willen, wenn hier viele schon mit dem alten, etablierten und bewährten C++ überfordert sind, was glaubst du ist erst bei einer neuartigen und innovativen (Ownershipsystem z.B.) Sprache los ist, die dazu auch noch die gleiche Mächtigkeit anstrebt. Vor allem wenn sich hier schon so wenige mit C++ auskennen, dann wird sich mit Rust wohl kaum schon einer beschäftigt haben (aber eine Meinung haben sie ganz sicher schon ;) ). Vincent H. schrieb: > Rust bietet ja quasi die Möglichkeit zur Abstraktion ohne eigentliche > Klassen? Ich würde jemanden bitten mir hier meine Meinung zu justieren, > ich weiß nämlich nicht ob ich Rust jetzt schlecht finden muss? Die structs sind doch quasi Klassen. Das OOP funktioniert dort ein bisschen anders (man könnte auch sagen, dass es reduzierter/vereinfachter ist), so ähnlich wie bei Go. Vererbung gibts an sich nicht, aber Traits (also Interfaces wie in C#/Java) und natürlich Komposition, womit sich sowas wie Vererbung nachbilden lässt. Mein erster Eindruck ist sehr gut, aber es ist keine Sprache für Anfänger sondern eher was für Leute, die viele Dinge an C++ zu schätzen wissen, aber mit ein paar Dingen nicht zu frieden sind.
Jörg W. schrieb: > Namend memory spaces sind Bestandteil eines Standardvorschlags für > Embedded C. Johann wollte darauf hinaus, dass dieser Vorschlag jedoch > auf einem standardmäßig bei C vorhandenen Feature basiert, den type > qualifiers, die es bei C++ nicht gibt. Wenn ich mich recht entsinne, kennt C die Typqualifizierer "const" und "volatile" erst seit C89 und hat sie lustigerweise ausgerechnet von C++ übernommen... correct me if I'm wrong. Zudem kommt IIRC __flash vom IAR, wurde von Atmel für den GCC übernommen, und ist bisher nur ein Vorschlag, aber eben kein Standard.
PeterPan schrieb: > Nop schrieb: >> [...] > Was willst du eigentlich ständig mit Torvalds? Der Linus ist eben dem Nop sein heiliger Gott, der immer Recht hat und sich noch niemals nie nicht geirrt hat. Und weil unserem Nop hier leider gerade die eigenen Argumente ausgegangen sind (so er denn überhaupt jemals welche gehabt haben sollte) und der Linux mal was gesagt hat, das dem Nop gefällt und ihm gerade in den "argumentativen" Kram paßt, darum reitet der Nop hier immer wieder auf dem Linus und seinen Aussagen herum, daß der arme Linus schon ganz wund dabei wird. > Gibt es überhaupt irgendwas auf der Welt worüber Linus keinen Rant > starten kann? Ja, Tove. ;-)
@nop: Mit dem was Du da von Dir gibst sagst Du, dass meine Kollegen und ich unsere Arbeit nicht richtig machen, weil wir diese Unsprache C++ hernehmen und uns damit sicher verkünsteln. Ich glaube Du kannst, wie es Dir hier viele schon nahe gelegt haben, C++ schlicht weg nicht ordentlich beurteilen, weil Du es einfach nicht richtig kennst. Somit ist dein Vermögen darüber qualifizierte Kommentare abzugeben nicht sonderlich groß. Sorry für die Direktheit, aber es ist nun mal so und Du willst es einfach nicht wahr haben. @all: Ihr hättest das hier mal lesen sollen, bevor ichs selbst zensiert hab :D Wär ja schade drum wenn die Kernaussage des Posts nicht stehen bleibt. Grüße Oliver
:
Bearbeitet durch User
Beitrag #5041032 wurde von einem Moderator gelöscht.
Sheeva P. schrieb: > Zudem kommt IIRC __flash vom IAR, Nicht nur, auch viele andere Compiler handhaben das so. Daher ja auch der Standardvorschlag. Solche Dinge werden ja nicht von den Normungsgremien erfunden, sondern sie bemühen sich in erster Linie, gängige Praxis zu standardisieren. > wurde von Atmel für den GCC > übernommen, Atmel? Die haben damit nichts zu tun. Das ist Johanns Werk. > und ist bisher nur ein Vorschlag, aber eben kein Standard. Besser als nichts. Insbesondere eben besser als das progmem-Attribut. Warum man named memory spaces im Embedded-Bereich gebrauchen kann, wurde ja schon genannt. Selbst wenn sie alle über einen flat address space zugegriffen werden können, kann es halt notwendig sein, dass der Programmierer verschiedene Speichersegmente selbst beim RAM explizit auswählen möchte. Ohne named memory spaces geht das nur über völlig proprietäre Lösungen, Pragmas, Attribute etc. pp.
Beitrag #5041043 wurde von einem Moderator gelöscht.
Beitrag #5041053 wurde von einem Moderator gelöscht.
Sheeva P. schrieb: >> Also mal ganz vulgär: >> nicht "SetzePin(Port,Nummer,Zustand);" >> sondern "SchalteMotorEin();" > > ...oder eben: "motor.einschalten();". Das läßt sich mit einfacher > Vererbung ganz einfach, elegant und kostenlos umsetzen. Das bedarf nur > einer simplen Elternklasse, die einen Pin abstrahiert -- und ist dann > mit einer anderen Elternklasse, die dasselbe Interface auf einer anderen > Controllerfamilie implementiert, sogar portabel. Nein, du fährst damit in die falsche Richtung. Für den Motor kann man kein Objekt gebrauchen, denn er läßt sich nicht ableiten (wovon denn auch!) - und Vererbung hat auch keinen Sinn, denn der Motor (oder der Schütz oder die Lampe) hat eben auch nichts zu vererben (an wen denn auch!). Objektorientierte Programmierung ist eine Domäne von äußerlich gleichen, aber innerlich verschiedenen Dingen, also von einem Vorfahren abgeleitete Objekte wie z.B. grafische Elemente auf dem Bildschirm. Aber das gilt ausdrücklich NICHT für Hardware. Die ist immer ein Unikat. Abgesehen davon denkst du schon wieder an etwas in der Art von vererbtem und abstrahierten Pin - das ist falsch, weil einschränkend. Sowas wie "SchalteMotorEin() kann auch das Aufsetzen eines Timermoduls sein, wenn es sich z.B. um einen Schrittmotor handelt. Es kann auch ein I2C Zugriff sein, wenn es ein intelligenter Stellmotor ist. Natürlich kann es auch ein simpler Schütz sein, der den Motor erstmal in Stern anlaufen läßt um dann nach einiger Zeit auf Dreieck umgeschaltet zu werden. Du siehst, daß sich sowas einfach NICHT oder nur mit sinnlos aufgesetztem Krampf in eine Objakthierarchie fassen läßt. Also, denke an "KISS" und laß als sinnvollste Schnittstelle die simple Aktion "SchalteMotorEin()" einfach stehen. Das ist so ziemlich die sinnvollste Abstraktion in diesem Falle. W.S.
W.S. schrieb: > Objektorientierte Programmierung ist eine Domäne von äußerlich gleichen, > aber innerlich verschiedenen Dingen, also von einem Vorfahren > abgeleitete Objekte wie z.B. grafische Elemente auf dem Bildschirm. Aber > das gilt ausdrücklich NICHT für Hardware. Die ist immer ein Unikat. Objektorientierung geht auch ohne Vererbung. Ein Objekt kann auch einfach nur zusammengehörige Sachen sehr schön kapseln. Man kann dann Abhängigkeiten bei Konstruieren mit reingeben (Composite-Pattern), was UnitTests erheblich erleichtert. Da kommt mir persönlich das was die Sprache C++ bietet sehr entgegen. Es setzt aber vorraus, dass man sich darauf einlässt beim Softwareentwurf in Objekten zu denken, sonst macht das natürlich wenig Sinn. Grüße Oliver
W.S. schrieb: > Objektorientierte Programmierung ist eine Domäne von äußerlich gleichen, > aber innerlich verschiedenen Dingen … also beispielsweise einem Dutzend Motoren eines Roboters? ;-)
:
Bearbeitet durch Moderator
Beitrag #5041100 wurde von einem Moderator gelöscht.
Beitrag #5041101 wurde von einem Moderator gelöscht.
Beitrag #5041105 wurde von einem Moderator gelöscht.
Beitrag #5041111 wurde von einem Moderator gelöscht.
Beitrag #5041113 wurde von einem Moderator gelöscht.
Beitrag #5041123 wurde von einem Moderator gelöscht.
Beitrag #5041134 wurde von einem Moderator gelöscht.
Beitrag #5041148 wurde von einem Moderator gelöscht.
Beitrag #5041154 wurde von einem Moderator gelöscht.
Oliver J. schrieb: > Ihr hättest das hier mal lesen sollen, bevor ichs selbst zensiert hab :D > Wär ja schade drum wenn die Kernaussage des Posts nicht stehen bleibt. Bitte, reg' Dich nicht auf. Ich weiß, angesichts der Ignoranz und der fast schon gebetsmühlenartig immer wieder vorgebrachten Vorurteile, die darüber hinaus aus Unkenntnis noch nicht einmal die eigenen sind, ist das manchmal leichter gesagt als getan. Aber nimm' es mit Humor: Du darfst und kannst die Vorzüge von C++ genießen, und er eben nicht. Selbstgewähltes Schicksal, nennt man das wohl. ;-)
Ich kann nur sagen keine Angst vor C++, jeder der C++ kann, kann auch C und teilweise auch umgekehrt. Ein guter Programmierer hat keine Angst vor verschiedenen Programmiersprachen, er kann sogar viele davon anwenden. Fürs Hobby lohnt sich der Aufwand freilich nicht viele Sprachen zu lernen. Wer kleine überschaubare Programme schreibt der nehme C, wer mehr will, nehme C++ aber verwende nicht die allzu verrückten Sachen, ich denke, dass man bei Klassen einen guten Schlussstrich machen kann.
Beitrag #5041164 wurde von einem Moderator gelöscht.
Jörg W. schrieb: > Sheeva P. schrieb: > >> wurde von Atmel für den GCC >> übernommen, > > Atmel? Die haben damit nichts zu tun. Das ist Johanns Werk. Wenn Du das sagst, wird das so sein. Ich hatte diese Seite [1] fälschlich so interpretiert, daß Atmel das Verdienst beansprucht. Entschuldige, Johann: ich wollte Deine hervorragenden Leistungen und Verdienste um den AVR-GCC nicht schmälern. >> und ist bisher nur ein Vorschlag, aber eben kein Standard. > > Besser als nichts. Ja, natürlich, keine Frage. Aber ein nützliches, dennoch aber (noch) nicht einmal standardisiertes einzelnes Feature einer Sprache als Argument gegen eine andere Sprache zu verwenden, während andererseits besonders wichtige, standardisierte Features wie etwa die wesentlich bessere Typsicherheit der anderen Sprache komplett ignoriert werden... verzeih', aber das erscheint mir weder seriös noch objektiv. [1] http://www.atmel.com/webdoc/avrlibcreferencemanual/porting_1iar_porting_flash.html
Beitrag #5041174 wurde von einem Moderator gelöscht.
Beitrag #5041175 wurde von einem Moderator gelöscht.
Sheeva P. schrieb: > Aber nimm' es mit Humor: Du darfst und kannst die Vorzüge von C++ > genießen, und er eben nicht. Selbstgewähltes Schicksal, nennt man das > wohl. ;-) Da hast Recht ;) Grüße Oliver
Beitrag #5041183 wurde von einem Moderator gelöscht.
Beitrag #5041188 wurde von einem Moderator gelöscht.
Beitrag #5041189 wurde von einem Moderator gelöscht.
Beitrag #5041191 wurde von einem Moderator gelöscht.
Sheeva P. schrieb: > Ich hatte diese Seite [1] fälschlich so interpretiert, daß Atmel das > Verdienst beansprucht. Das ist weiter nichts als die avr-libc-Dokumentation, was sie da wiedergeben. Dass sie da ein “© 2016 Atmel Corporation. All rights reserved” drüberknallen, ist eine mittelmäßige Frechheit. Da sie sich außerdem nicht an die Copyright-Bedingungen der avr-libc halten, werde ich (als einer der Autoren dieser Dokumentation) ihnen mal ein paar Zeilen schreiben müssen … Das von dir zitierte Kapitel könnte in der Tat mal einen Update gebrauchen, um auf das mittlerweile vorhandene __flash im AVR-GCC hinzuweisen.
W.S. schrieb: > Sheeva P. schrieb: >>> Also mal ganz vulgär: >>> nicht "SetzePin(Port,Nummer,Zustand);" >>> sondern "SchalteMotorEin();" >> >> ...oder eben: "motor.einschalten();". Das läßt sich mit einfacher >> Vererbung ganz einfach, elegant und kostenlos umsetzen. Das bedarf nur >> einer simplen Elternklasse, die einen Pin abstrahiert -- und ist dann >> mit einer anderen Elternklasse, die dasselbe Interface auf einer anderen >> Controllerfamilie implementiert, sogar portabel. > > Nein, du fährst damit in die falsche Richtung. Ich fürchte, daß Du hier gerade der Geisterfahrer bist. > Für den Motor kann man kein Objekt gebrauchen, denn er läßt sich nicht > ableiten (wovon denn auch!) - und Vererbung hat auch keinen Sinn, denn > der Motor (oder der Schütz oder die Lampe) hat eben auch nichts zu > vererben (an wen denn auch!). Zunächst einmal wird der Motor (zumindest Dein vereinfachtes Modell, das nur die Zustände "ein" und "aus" kennt) aus Sicht des Mikrocontrollers über einen GPO-Pin angesteuert. Für den Mikrocontroller ist Dein Motor darum nur ein GPO-Pin, der die Zustände "an" und "aus" hat und dessen aktueller Zustand nur über die Operationen (OO-Slang: Methoden) "einschalten" und "ausschalten" verändert werden kann. An dieser Stelle kommen bereits zwei wichtige Eigenschaften der OOP zum Tragen. Datenkapselung heißt an dieser Stelle, daß der Zustand des Motors nur über die Operationen (im OO-Slang manchmal auch Nachrichten genannt) "einschalten" und "ausschalten" verändert werden kann. Und die Vererbung heißt hier, daß der Motor in Wirklichkeit nur ein GPO-Pin ist, in der OO wird ein solcher Beziehungstyp als "is-a" bezeichnet. Genau dasselbe gilt auch für das Fahrlicht: dieselben Zustände, dieselben Operationen, aus Sicht des Mikrocontrollers im Prinzip dasselbe Ding: ein GPO-Pin. Dazu existieren in meinem objektorientierten Fahrzeug auch Bedienelemente, etwa die Zündung und der Schalter für das Fahrlicht mit den Zuständen "ein" und "aus", letzten Endes wieder mit "is-a" Beziehungen zu je einem GPI-Pin. Deswegen kann ich in meiner Steuerungssoftware also etwas schreiben wie:
1 | int main(void) { |
2 | while(true) { |
3 | if( zuendung.ist_an() ) { |
4 | motor.einschalten(); |
5 | } else { |
6 | motor.ausschalten(); |
7 | }
|
8 | }
|
9 | }
|
Was dieser Code tut, das verstehen Du, ich, meine Ehefrau und sogar meine zwölfjährige Zicke von Nichte auf den ersten Blick, weil der Code so schön deskriptiv ist und die bekannten Objekte der realen Welt nachbildet -- und Du wirst zurecht einwenden, daß das sehr ähnlich ja auch ohne OO geht. Aber bis hierher ist das ja nur Objektorientierung für Arme, um den Code etwas kompakter und lesbarer zu machen. Modellieren wir die Sache doch mal richtig: jetzt empfängt unser Motor, der immer noch nur ein GPO-Pin mit den Zuständen "hi" und "lo" ist, eine Nachricht vom Typ Zündung, und bietet dafür die Methode schalten(Zuendung z):
1 | int main(void) { |
2 | while(true) { |
3 | motor.schalten(zuendung); |
4 | }
|
5 | }
|
Ok, die Methoden sind blöd benannt, aber darum geht es gar nicht. Es geht vielmehr darum, daß unser Motor nur und ausschließlich mit der Zündung ein- und ausgeschaltet werden und sich darauf verlassen kann, daß die Zündung die passende Methode "ist_an" zur Ermittlung ihres Zustandes bietet. Das freut Dich spätestens dann, wenn Du mit Deinem Fahrzeug an einer Wettfahrt teilnehmen willst und dann noch einen Notaus-Knopf anbringen und in die Steuerung einbauen mußt: dann mußt Du nämlich nur die Klasse Zündung um Deinen Notaus-Knopf erweitern, aber der Motor und der gesamte Rest des Fahrzeuges bleibt komplett unberührt: "ist_an()" gibt eben nur dann true zurück, wenn a) die Zündung eingeschaltet und b) der Notausschalter nicht gedrückt worden ist. Nun, machen wir uns nichts vor: diese winzigen Beispiele sind zu klein und zu schnell aus der Hand geschüttelt, um die Stärken der OO zu zeigen. Aber sie sollen Dir ja auch nur eine kleine Idee davon geben. > Objektorientierte Programmierung ist eine Domäne von äußerlich gleichen, > aber innerlich verschiedenen Dingen, also von einem Vorfahren > abgeleitete Objekte wie z.B. grafische Elemente auf dem Bildschirm. Das ist zwar richtig, aber auch falsch. Im vorherigen zweiten Beispiel "weiß" unser Motor plötzlich, wie bzw. womit er ein- und ausgeschaltet wird, und kann den Zustand der Zündung daher selbständig abfragen. Er ist nicht mehr darauf angewiesen, daß wir ihm explizit sagen, was er tun soll, sondern er "weiß" es selbst. > Aber > das gilt ausdrücklich NICHT für Hardware. Die ist immer ein Unikat. Ich weiß nicht, was Du entwickelst, aber schon auf kleineren AVRs gibt es häufig mehrere U(S)ARTs, die also keineswegs Unikate sind, sondern Objekte mit (mehr oder weniger) denselben Eigenschaften. Ganz verwegene Entwickler lassen sogar unterschiedliche Protokolle über die verschiedenen U(S)ARTs ein- und desselben Mikrocontrollers laufen -- aber trotzdem sind es immer verschiedene U(S)ARTs. > Abgesehen davon denkst du schon wieder an etwas in der Art von vererbtem > und abstrahierten Pin - das ist falsch, weil einschränkend. Sowas wie > "SchalteMotorEin() kann auch das Aufsetzen eines Timermoduls sein, wenn > es sich z.B. um einen Schrittmotor handelt. Es kann auch ein I2C Zugriff > sein, wenn es ein intelligenter Stellmotor ist. Natürlich kann es auch > ein simpler Schütz sein, der den Motor erstmal in Stern anlaufen läßt um > dann nach einiger Zeit auf Dreieck umgeschaltet zu werden. Ja, natürlich kann das alles sein. Aber wo steht, daß eine Klasse Motor zwingend von einem GPO-Pin erben muß? "motor.einschalten()" kann genau dasselbe, was Deine Funktion auch kann: einen Timer aufsetzen, einen I2C-Zugriff auslösen oder ein Schütz schalten. Letztlich ist die Methode "einschalten()" ja auch nur eine Funktion und die Klasse "Motor" eine zustandsbehaftete Datenstruktur mit Methoden zur Änderung des Zustands. > Du siehst, > daß sich sowas einfach NICHT oder nur mit sinnlos aufgesetztem Krampf in > eine Objakthierarchie fassen läßt. Nein, das sehe ich nicht. Was ich sehe, ist klar verständlicher Code, der hohe Typsicherheit mit guter Les- und Erweiterbarkeit verbindet. Wo da ein "Krampf" sein soll, obendrein ein "sinnloser", erschließt sich mir nicht. > Also, denke an "KISS" und laß als sinnvollste Schnittstelle die simple > Aktion "SchalteMotorEin()" einfach stehen. Das ist so ziemlich die > sinnvollste Abstraktion in diesem Falle. Das sehe ich immer noch nicht so, tut mir leid.
Beitrag #5041241 wurde von einem Moderator gelöscht.
Beitrag #5041243 wurde von einem Moderator gelöscht.
Sheeva P. schrieb: > int main(void) { > while(true) { > motor.schalten(zuendung); > } > } > > Ok, die Methoden sind blöd benannt, aber darum geht es gar nicht. Es > geht vielmehr darum, daß unser Motor nur und ausschließlich mit der > Zündung ein- und ausgeschaltet werden und sich darauf verlassen kann, > daß die Zündung die passende Methode "ist_an" zur Ermittlung ihres > Zustandes bietet. Das verstehe ich als lernwilliger aber C++ ahnungsloser wie folgt. Für einen C++ Progger ist hier ein Objekt mit ner Eigenschaft und ner Anweisung. Vermute ich mal. Das ganze noch gekapselt, wie auch immer das jetzt funzen mag. In C würde das ähnlich aussehen. Die Funktion hält die Statis local (static), die ganze Steuerung läuft über function calls. Wer dann unbedingt noch motor.schalten haben will macht das per struct. Nicht ganz so hübsch zu schreiben, dafür spart man sich eine Menge undurchsichtiger Zusammenhänge. In der Regel hat man noch den Schaltplan, die Mechanik, Thermales, dynamic currents, EMI uswusf, zu beachten. Da ist die schöne OOP Toolchain eher akdemisch. Auch steigt man bei C (um doch nochmal die Abstraktionsebenen von weiter oben zu bemühen) da wesentlich besser durch als mit Assembler. Ein Problem lösen aber weder C noch C++. Wenn irgendein depp (üblicherweise der Autor) die Ports über andere Routinen toggelt und dabei statis ignoriert bzw falsch setzt schießt er die schöne Steuerung nebst Motor. Ohne das ich was machen kann. Wie auch? Weder µP-Hardware noch der Compiler können das verhindern. Das geht nur in Hardware, Thema Eigensicherheit (die zu der Liste der Aufgaben noch dazu kommt). Fazit bisher: OOP auf'm uC ist ein Randproblem.
X4Ubbb schrieb: > Wenn irgendein depp (üblicherweise der Autor) die Ports über andere > Routinen toggelt und dabei statis ignoriert bzw falsch setzt schießt er > die schöne Steuerung nebst Motor. Ohne das ich was machen kann. Wie > auch? Weder µP-Hardware noch der Compiler können das verhindern. > > Das geht nur in Hardware, Thema Eigensicherheit (die zu der Liste der > Aufgaben noch dazu kommt). > > Fazit bisher: OOP auf'm uC ist ein Randproblem. Genau aus dem Grund haben Klassen private und public Member. Ein Motor Pin ist ein internes Detail des Motors und damit von außen nicht zugreifbar.
X4Ubbb schrieb: > Wenn irgendein depp (üblicherweise der Autor) die Ports über andere > Routinen toggelt und dabei statis ignoriert bzw falsch setzt schießt er > die schöne Steuerung nebst Motor. Ohne das ich was machen kann. Wie > auch? Weder µP-Hardware noch der Compiler können das verhindern. Der Compiler zwar nicht allein, aber mit (etwas mehr) Template-Mechanik bekommt man auch das in den Griff. > Das geht nur in Hardware, Thema Eigensicherheit (die zu der Liste der > Aufgaben noch dazu kommt). > > Fazit bisher: OOP auf'm uC ist ein Randproblem. Entwickelt sich das jetzt hier zu einem Grundkurs in OOD?
X4Ubbb schrieb: > > Nicht ganz so hübsch zu schreiben, dafür spart man sich eine Menge > undurchsichtiger Zusammenhänge. In der Regel hat man noch den > Schaltplan, die Mechanik, Thermales, dynamic currents, EMI uswusf, zu > beachten. Da ist die schöne OOP Toolchain eher akdemisch. > > Auch steigt man bei C (um doch nochmal die Abstraktionsebenen von > weiter oben zu bemühen) da wesentlich besser durch als mit Assembler. Ich weiß nicht, was dieses ganze Gerede um zu starke Abstraktion soll. Wenn ich schreibe
1 | std::iota(std::begin(c), std::end(c), 42); |
weiß ich, dass danach der Container c mit einer Folge von ganzen Zahlen beginnend mit 42 gefüllt ist. Ich muss weder wissen, WAS es für ein Container ist, etwa eine rohes Array, ein std::array, ein std::vector, ein selbst-geschriebener ... Das ist ein generischer Algorithmus, und der tut, was er soll. Da WILL ich doch gar nicht hinein sehen, wie std::iota<>() realisiert ist.
:
Bearbeitet durch User
X4Ubbb schrieb: > Fazit bisher: OOP auf'm uC ist ein Randproblem. Ja, aus Sicht des E-Technikers für den Software ein nötiges Übel ist. Und so scheinen viele Geräte programmiert zu sein. Gruseliger C Code den nur der Autor versteht und wenn das Projekt vererbt wird muss der nächste erstmal alles neu machen. X4Ubbb schrieb: > In C würde das ähnlich aussehen. Die Funktion hält die Statis local > (static), die ganze Steuerung läuft über function calls. Wer dann > unbedingt noch motor.schalten haben will macht das per struct. Mit solchen Lösungen hatte ich früher reichlich zu tun und das waren die häufigsten Fehlerquellen weil der 'Progger' (kindische Bezeichnung) zu faul war Indizes oder Pointer zu überprüfen was bei dieser Lösung nötig ist. Bei C++ geht man vom Design her anders ran weil die Sprache es hergibt und man nicht mit Compiler Klimmzügen Sicherheit reinbringen muss. Beim Beispiel mit dem Motor brauche ich keine Abstraktion, der motor ist ein DigitalOut (im einfachen Fall) und ein 'motor = 1' schaltet den ein. So ein Motor ist in der realen embedded Welt aber nicht so einsam und gehört zu einer Baugruppe die einen Namen und Funktionen hat und wunderbar als Objekt abgebildet werden kann, zB eine Antriebsachse mit Endschaltern. Das packt man mit den nötigen Funktionen und internen Zuständen in eine Klasse. Und wenn man mehrere Achsen hat sind es ganz einfach mehrere Instanzen. Die Ersatzlösung in C die das nachbilden möchte muss jetzt ein Argument für die Achsenauswahl in jede Funktion bekommen. Ein einfacher numerischer Index ist kein sicherer Typ und man kann nur den Wertebereich auf Gültigkeit prüfen. Pointer oder Handles sind aufwändiger und evtl. noch gefährlicher bei falscher Benutzung. Alleine diese Kapselung ist für mich Grund genug lieber mit C++ zu arbeiten, auch und gerade auf µCs weil sich die Komponenten gut in Objekten abbilden lassen. Und solange ich eine konrete Anwendung habe brauche ich keine wilden Abstraktionen.
Vincent H. schrieb: > X4Ubbb schrieb: >> Wenn irgendein depp (üblicherweise der Autor) die Ports über andere >> Routinen toggelt und dabei statis ignoriert bzw falsch setzt schießt er >> die schöne Steuerung nebst Motor. Ohne das ich was machen kann. Wie >> auch? Weder µP-Hardware noch der Compiler können das verhindern. >> >> Das geht nur in Hardware, Thema Eigensicherheit (die zu der Liste der >> Aufgaben noch dazu kommt). >> >> Fazit bisher: OOP auf'm uC ist ein Randproblem. > > Genau aus dem Grund haben Klassen private und public Member. Ein Motor > Pin ist ein internes Detail des Motors und damit von außen nicht > zugreifbar. Leider ist das der Peripherie des µC egal. Der µC führt ja bloß den Binärcode aus, der auf Register zugreift. Wenn also ein Timer von anderer Stelle so konfiguriert wird, dass er ne PWM auf dem selben Pin aktiviert oder ein UART dahinter angeschaltet wird, dann hat man konkurrierenden zugriff auf den Pin. Davor schützen weder Klassen noch Compiler, da die nichts von der "Verdrahtung" der Register mit der Hardware wissen. Es könnten auch zwei Klassen den selben Pin als GPIO verwenden. Das macht im Normalfall natürlich keiner, aber wenn sich der Fehlerteufel einschleicht, kann sowas schon mal passieren. Icdh denke in diese Richtung hat das abgezielt. X4Ubbb schrieb: > Nicht ganz so hübsch zu schreiben, dafür spart man sich eine Menge > undurchsichtiger Zusammenhänge. Für wen undurchsichtig? Wahrscheinlich für jemanden ohne C++ Erfahrung. X4Ubbb schrieb: > Fazit bisher: OOP auf'm uC ist ein Randproblem. Als Problem würde ich das eher nicht sehen. Es ist eher bei weitem noch nicht so oft vertreten wie klassische Ansatz, aber das kann sich ja noch ändern. Wilhelm M. schrieb: > std::iota(std::begin(c), std::end(c), 42); Geht das wirklich bei avr mit Standardmitteln? Grüße Oliver
:
Bearbeitet durch User
Oliver J. schrieb: > > Wilhelm M. schrieb: >> std::iota(std::begin(c), std::end(c), 42); > Geht das wirklich bei avr mit Standardmitteln? Selbstverständlich. Was sollte das auch mit C++ als Sprache zu tun haben? Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund ;-). Aber man kann natürlich die benötigten templates wie std::iota und std::begin oder std::end oder auch std::array sich gerade selbst schreiben (oder aus der Libstdc++ abkupfern, wenn man das nicht will/kann). std::vector vllt eher nicht, da man hier dann dyn. Allokation braucht.
Wilhelm M. schrieb: > Selbstverständlich. > .. > Aber man kann natürlich die benötigten templates wie std::iota und > std::begin oder std::end oder auch std::array sich gerade selbst > schreiben ... Man kann nicht, man muß. Was die Definition von "selbstverständlich" dann doch etwa relativiert. Aber die Welt besteht zum Glück nicht nur aus AVRs. Oliver
Oliver S. schrieb: > Wilhelm M. schrieb: >> Selbstverständlich. >> .. >> Aber man kann natürlich die benötigten templates wie std::iota und >> std::begin oder std::end oder auch std::array sich gerade selbst >> schreiben ... > > Man kann nicht, man muß. Was die Definition von "selbstverständlich" > dann doch etwa relativiert. ... das wäre dann eine gute Fingerübung für die, die hier mitreden wollen ;-) > > Aber die Welt besteht zum Glück nicht nur aus AVRs. Genau!
Wilhelm M. schrieb: > Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund > ;-) Und was ist dieser Grund? Du als C++ Hero wärst doch prädestiniert, den GCC so zu pimpen, dass er auch C++ unterstützt.
Johann L. schrieb: > Wilhelm M. schrieb: >> Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund >> ;-) > > Und was ist dieser Grund? > > Du als C++ Hero wärst doch prädestiniert, den GCC so zu pimpen, dass er > auch C++ unterstützt. Was meinst Du? Tut er doch, der avr-g++. Sogar z.B. __underlying_type funktioniert ... Nur - wie gesagt - die dynamischen Container der Libstdc++ machen auf diesen kleinen µC wenig bis gar keinen Sinn. Auf anderen dagegen schon.
Wilhelm M. schrieb: > Johann L. schrieb: >> Wilhelm M. schrieb: >>> Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund >>> ;-) >> >> Und was ist dieser Grund? >> >> Du als C++ Hero wärst doch prädestiniert, den GCC so zu pimpen, dass er >> auch C++ unterstützt. > > Was meinst Du? Tut er doch, der avr-g++. Nein, tut er nicht, denn zum C++ Standard gehören eben auch die Standard-Bibliotheken, nicht nur der Sprachkern. Und den "guten Grund", warum dieser Teil von C++ nicht unterstützt wird, kenn ich auch nicht.
Beitrag #5041437 wurde von einem Moderator gelöscht.
Beitrag #5041444 wurde von einem Moderator gelöscht.
Johann L. schrieb: > Wilhelm M. schrieb: >> Johann L. schrieb: >>> Wilhelm M. schrieb: >>>> Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund >>>> ;-) >>> >>> Und was ist dieser Grund? >>> >>> Du als C++ Hero wärst doch prädestiniert, den GCC so zu pimpen, dass er >>> auch C++ unterstützt. >> >> Was meinst Du? Tut er doch, der avr-g++. > > Nein, tut er nicht, denn zum C++ Standard gehören eben auch die > Standard-Bibliotheken, nicht nur der Sprachkern. Stimmt! Ich sprach aber oben von avr-g++ und nicht vom gesamten C++-Standard. > Und den "guten Grund", warum dieser Teil von C++ nicht unterstützt wird, > kenn ich auch nicht. Der Grund ist m.E. zweiteilig: 1) Allgemeine, unbeschränkte dyn. Container machen auf so kleinen µCs keinen Sinn. 2) Mit 1) hätten wir dann nur eine "halbe" Libstdc++, was auch keinen Sinn macht. Aber: mit Bibliotheken wie z.B. ETL ist diese halbe Libstdc++ ja verfügbar.
Beitrag #5041448 wurde von einem Moderator gelöscht.
Beitrag #5041460 wurde von einem Moderator gelöscht.
Beitrag #5041464 wurde von einem Moderator gelöscht.
Beitrag #5041511 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund > ;-). Es gibt keinen „guten Grund“, höchstens einen schlechten: es hat sich lange Zeit kein Schwein drum gekümmert, das mal zum Laufen zu bekommen. Offensichtlich war der Leidensdruck für die C++-Nutzer nicht sehr hoch, vollständige Sprachunterstützung auch aus Bibliothekssicht zu haben. Vor einiger Zeit gab es mal wieder eine Initiative, es wurde auch bisschen was dafür in der regulären avr-libc angepasst, aber seither ist es wieder ruhig geworden darum. Keine Ahnung, wie der aktuelle Stand da wirklich ist. Ob nun dynamische Objekte Sinn haben oder nicht, braucht man nicht aus Sicht der Sprache zu argumentieren: dynamische Probleme lassen sich nur dynamisch lösen, für statische Probleme wiederum zieht man sich das sowieso nicht rein. Die C-Bibliothek hat ja auch ein malloc(), das beißt keinen in die Wade, solange man es nicht benutzt …
Wieso wird hier über Abstraktion geschimpft bzw. solche Codebeispiele gegenüber gestellt. Jeder von euch nutzt doch C oder C++ oder sonst was zum Programmieren, das ist schon eine enorme Abstraktion im Vergleich zum Assembler. Von fertigen Bibliotheken will ich gar nicht anfangen zu reden und dennoch nutzt jeder sie gerne. Sinn und Zweck einer Sprache muss es sein Dinge einfacher und effizienter zu machen und das tut C++ nun mal besser als C usw. Beide Sprachen sind aber nah genug an der Hardware weil es eben kompilierte Sprachen sind. Die Tragweite der Abstraktion im Programm selbst hat man doch selbst in der Hand, in C++ muss ich nicht zwingend Klassen verwenden, C++ bietet mir lediglich die Möglichkeit, ich kann aber 100% prozedural wie in C auch coden wenn ich will. Aber Klassen mit Vererbung, Nutzung gleicher Funktionsnamen und Variablen in verschiedenen Klassen ist schon eine tolle Sache um ein paar Dinge zu nennen.
Beitrag #5041552 wurde von einem Moderator gelöscht.
christopher robin schrieb: > Wieso wird hier über Abstraktion geschimpft bzw. solche Codebeispiele > gegenüber gestellt. Jeder von euch nutzt doch C oder C++ oder sonst was > zum Programmieren, das ist schon eine enorme Abstraktion im Vergleich > zum Assembler. Von fertigen Bibliotheken will ich gar nicht anfangen zu > reden und dennoch nutzt jeder sie gerne. Ja. Man möchte nicht jedes Mal wieder eine neue Tastaturabfrage oder ein Protokoll neu aufbauen. Heute muss ich sagen: Gottseidank haben ich/wir damals die Hardware in unseren Bibliotheken abstrahiert. Nur so war der Umzug von AVR auf deutlich leistungsfähigere STM32 ohne größere Schmerzen möglich. Fortschritt in der IT lebt davon, dass wir mehr und mehr abstrahieren - schon weil der Mensch gar nicht in der Lage ist, beliebige viele Dinge gleichzeitig zu überblicken. > Die Tragweite der Abstraktion im Programm selbst hat man doch selbst in > der > Hand, in C++ muss ich nicht zwingend Klassen verwenden, C++ bietet mir > lediglich die Möglichkeit, ich kann aber 100% prozedural wie in C auch > coden wenn ich will. Aber Klassen mit Vererbung, Nutzung gleicher > Funktionsnamen und Variablen in verschiedenen Klassen ist schon eine > tolle Sache um ein paar Dinge zu nennen. Das habe ich als Argument lange vermisst: C++ ist doch eine Obermenge von C. C++ enthält ja nicht nur OOP-Komponenten, sondern eben auch andere schöne Dinge (Namespaces usw.), die man auch bei rein prozeduraler Programmierung nutzen kann.
Jörg W. schrieb: > Wilhelm M. schrieb: >> Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund >> ;-). > > Es gibt keinen „guten Grund“, höchstens einen schlechten: es hat > sich lange Zeit kein Schwein drum gekümmert, das mal zum Laufen zu > bekommen. Offensichtlich war der Leidensdruck für die C++-Nutzer nicht > sehr hoch, vollständige Sprachunterstützung auch aus Bibliothekssicht > zu haben. M.E. ist eine 100%-Kompatibilität zur STL auch nicht erstrebenswert für die Anwendung auf so kleine µC wie die AVRs. Das fängt mit dynamischen Containern an, die nicht unkontrolliert wachsen dürfen. In der STL gibts eine Exception (auch die wollen wir auf µC nicht), wenn der Allokator kein Element mehr allokieren kann. Verändert man die Semantik des Containers zu einem mit begrenzter Kapazität und will man keine Exception, muss man an der Schnittstelle bspw. von std::vector was verändern, etwa void push_back() zu bool push_back(), oder auch void pop_front() zu bool pop_front(), da man auch kein UB akzeptieren kann. Und wenn man nicht 100% kompatibel sein kann, sollte man es lassen. Das ist m.E. ein guter Grund. Und deswegen wird sich da auch keiner drum kümmern. Und wie gesagt: es gibt ja bereits Ersatz ...
Wilhelm M. schrieb: > M.E. ist eine 100%-Kompatibilität zur STL auch nicht erstrebenswert Dem Fuchs waren die Trauben damals auch zu sauer …
Chris D. schrieb: > > Das habe ich als Argument lange vermisst: C++ ist doch eine Obermenge > von C. Leider nicht. Es gibt filigrane Unterschiede z.B. wann UB entsteht. Der Klassiker sind unions und der Zugriff auf das "non-active-member". > C++ enthält ja nicht nur OOP-Komponenten, sondern eben auch andere > schöne Dinge (Namespaces usw.), die man auch bei rein prozeduraler > Programmierung nutzen kann. Das ist doch gerade das, was ich hier schon zum x-ten Mal sage: C++ ist eine Multiparadigmen-Sprache (vielleicht weiß ja keiner was damit gemeint ist ...): also mindestsmal kann ich auch nur rein prozedural und imperativ programmieren. Man muss ja nicht gleich eine DSL (nein: nicht Telekom ...) implementieren oder funktional werden. Und es gibt eben so viele kleine Nettigkeiten, die wirklich Freude machen: zuallererst domänenspezifische Datentypen etwa Länge[m], Strom[A], Ladung[C], ...
Beitrag #5041585 wurde von einem Moderator gelöscht.
Beitrag #5041616 wurde von einem Moderator gelöscht.
Beitrag #5041662 wurde von einem Moderator gelöscht.
Jörg W. schrieb: >> Objektorientierte Programmierung ist eine Domäne von äußerlich gleichen, >> aber innerlich verschiedenen Dingen > > … also beispielsweise einem Dutzend Motoren eines Roboters? ;-) Genau. Und bei jedem Motor ist die Ansteuerung ganz anders, weswegen jeder seine eigenen Methoden haben muß und sich keinerlei Gemeinsamkeit findet, wenn man mal vom Wort "Motor" absieht. Was hast du denn von einer Klasse "Motor", wenn jeder Motor seinen eigenen Satz Methoden haben muß? Oder jedem Motor seine eigene Klasse, die mit der des Nachbarmotors nix zu schaffen hat? Die Alternative sähe so aus, daß man alles bei allen Motoren parametrisieren müßte, um auf gleiche Methoden kommen zu können. Aber das bläht die Treiber derart auf, daß man es lieber bleiben lassen sollte. W.S.
Beitrag #5041804 wurde von einem Moderator gelöscht.
Beitrag #5041806 wurde von einem Moderator gelöscht.
Beitrag #5041818 wurde von einem Moderator gelöscht.
W.S. schrieb: > Jörg W. schrieb: >>> Objektorientierte Programmierung ist eine Domäne von äußerlich gleichen, >>> aber innerlich verschiedenen Dingen >> >> … also beispielsweise einem Dutzend Motoren eines Roboters? ;-) > > Genau. Und bei jedem Motor ist die Ansteuerung ganz anders, weswegen > jeder seine eigenen Methoden haben muß und sich keinerlei Gemeinsamkeit > findet, wenn man mal vom Wort "Motor" absieht. Was hast du denn von > einer Klasse "Motor", wenn jeder Motor seinen eigenen Satz Methoden > haben muß? Oder jedem Motor seine eigene Klasse, die mit der des > Nachbarmotors nix zu schaffen hat? > > Die Alternative sähe so aus, daß man alles bei allen Motoren > parametrisieren müßte, um auf gleiche Methoden kommen zu können. Aber > das bläht die Treiber derart auf, daß man es lieber bleiben lassen > sollte. > > W.S. Nur weil ein Schritt- und ein Encoder-gestützer DC Motor andere Ansteuerungen haben, heißt das doch noch lange nicht, dass ich nicht beide mit "Motor::move(x, y, z)" ansprechen kann... Nona brauch ich für jeden Motor eine eigene Implementierung. Hab ich die aber einmal fertig, so ist mir später einmal egal ob ich mit einer move Funktion jetzt den Schritt- oder den DC Motor steuere. Bei diesem Komfort hört die objektorientierte Abstraktion aber nicht auf. Wird das Projekt später einmal erweitert und eine Asynchronmaschine eingebaut, so zwinge ich mit dem bestehenden Code dem neuen Motor exakt das selbe Interface auf. Damit unterbinde ich von vornherin, dass ein Kollege aus Jux und Tollerei eine "goto" Funktion mit Polar-Koordinaten schreibt...
PeterPan schrieb: > Ich frage mich wie du dann überhaupt C in Betracht ziehen kannst, eine > Sprache die nicht mal sowas wie echte Konstanten kennt (const wohl eher > nicht...). Na, in C++ ist "const" auch nicht das, was man unter "konstant" oder "read-only" versteht. Instruktives Beispiel:
1 | extern const int c; |
2 | |
3 | __attribute__((__used__)) |
4 | const int i = c; |
mach avr-g++ zu
1 | _GLOBAL__sub_I_const.c: |
2 | lds r24,c |
3 | lds r25,c+1 |
4 | sts _ZL1i+1,r25 |
5 | sts _ZL1i,r24 |
6 | ret |
7 | .size _GLOBAL__sub_I_const.c, .-_GLOBAL__sub_I_const.c |
8 | .global __do_global_ctors |
9 | .section .ctors,"a",@progbits |
10 | .p2align 1 |
11 | .word gs(_GLOBAL__sub_I_const.c) |
12 | .local _ZL1i |
13 | .comm _ZL1i,2,1 |
D.h. es wird ein statischer Konstruktor aus dem Hut gezaubert (geht halt nicht anders) um i zu initialisieren. Wenn du nun PROGMEM verwendest weil du glaubst, const i sei read-only: BUMMER. Natürlich ist i read-only auf C++ Ebene, aber eben nicht read-only auf Binärebene, und C++ kann offenbar auch keine solche Zusicherung machen. Dafür brauchte es dann eine Spracherweiterung wie constexpr. Welche Zusicherungen die auf Binärebene macht weiß ich nicht. Da der Standard darüber (z.B. elf oder aout) keine Annahmen macht, stell ich mir die Spezifikation ganz interessant vor... Wenn es hingegen in C übersetzt, dann ist es read-only auf Binäreben -- und wenn es nicht übersetzt, bedeutet das nicht, dass es im landläufigen Sinne nicht konstant ist. Ist zwar eine Einschränkung in C, dafür weiß ich aber was rauskommt wenn es compiliert.
Johann L. schrieb: > PeterPan schrieb: >> Ich frage mich wie du dann überhaupt C in Betracht ziehen kannst, eine >> Sprache die nicht mal sowas wie echte Konstanten kennt (const wohl eher >> nicht...). > > Na, in C++ ist "const" auch nicht das, was man unter "konstant" oder > "read-only" versteht. Oft ein Mißverständis, was const bedeutet! Hier ist ein gutes Beispiel, das auch noch aus der µC Welt stammt, und deswegen hier verständlich sein sollte. https://stackoverflow.com/questions/4486326/does-const-just-mean-read-only-or-something-more Zum Big Picture hinter const: https://isocpp.org/wiki/faq/const-correctness Und die Bedeutung von constexpr ist nochmal anders ...
:
Bearbeitet durch User
Wilhelm M. schrieb: > Johann L. schrieb: >> PeterPan schrieb: >>> Ich frage mich wie du dann überhaupt C in Betracht ziehen kannst, eine >>> Sprache die nicht mal sowas wie echte Konstanten kennt (const wohl eher >>> nicht...). >> >> Na, in C++ ist "const" auch nicht das, was man unter "konstant" oder >> "read-only" versteht. > > Oft ein Mißverständis, was const bedeutet! Ich wollte nur darauf hingewiesen haben, dass const in C++ eben nicht konstant ist von der binär-Perspektive. Auf einem Host ist mir das relativ Wurscht, aber je limitierter die Zielplattform ist, desto exakter muss die Code-Erzeugung sein. Und an C++ für AVR interessiert mich zumindest immer auch welchen Code der Compiler generiert, einfach weil ich immer auch die Tool-Perspektive habe.
Beitrag #5041940 wurde von einem Moderator gelöscht.
Beitrag #5041976 wurde von einem Moderator gelöscht.
Johann L. schrieb: >> Oft ein Mißverständis, was const bedeutet! > > Ich wollte nur darauf hingewiesen haben, dass const in C++ eben nicht > konstant ist von der binär-Perspektive. Die C++-Konstanten sind i.Allg. schon etwas konstanter als diejenigen in C, aber noch lange nicht konstant genug, um bspw. folgendes zu machen:
1 | extern const int c; |
2 | |
3 | const int i = c; |
4 | int array[i]; |
Ich will unbedingt noch in Errinnerung rufen, dass der erste C++ Compiler CFront (und folgende andere frühe C++ Compilers) nicht direkt Maschinencode sondern C-Code generierten. Für die Zankdiskussion hier: man schrieb in C Quellcode, mit dem man nichts zu tun haben wollte. Man wendet in der neuen Sprache C++ "ach so fürchterliche" OO-Konzepte an, welche sich in der alten Sprache C zwar auch formulieren lassen, aber in einer (wegen C) gezwungenermassen dermassen schrecklichen Form ausfallen, auf die man keine Lust hat sie von Hand weder direkt so hinzuschreiben noch zu warten, sodass eben einen Automaten (der Umsetzer) ran muss damit man nur in der "weniger schrecklichen" neuen Formulierung bleiben kann. Das ist übrigens eine sehr verbreitete Vorgehensweise, welche bewährt und akzeptiert ist. Nicht nur dass "damals" aus dem Verdruss in Assembler/Maschinensprache immer wieder den selben boilerplate Code durchkauen zu müssen BASIC/FORTRAN/C/usw. entstanden -alle diese Programmiersprachen haben ziemlich überschaubare "schlimme" aber eben doch sinnvollerweise nötige Abstraktionen resp. Äquivalenzen zu was man davor machte- sondern auch neuzeitigere, junge, "ach so fürchterlich Abstrakte" Programmiersprachen lassen sich so umsetzen: p2c, ptoc, Ofront, m2c, GNAT, u.v.A.mehr. Auch für die JVM gibt es mehr als bloss Java. LLVM lässt ebenso grüssen. Letztendlich werden alle Programme, egal in welcher Sprache sie geschrieben sind, von den CPUs in Maschinencode ausgeführt. C-isten, welche C++-isten den nächsten "fürchterlichen" Schritt richtung Hochsprache wegzetern wollen sollen bedenken dass sie selbst auf dem gleichen Gefälle und in gleicher Position gegenüber ASM-isten sind. Für alle 3 genannten Gruppen gilt: jeder darf bei seinem Lieblingswerkzeug bleiben, solange es ihm gut von der Hand geht und egal wie umständlich es tatsächlich ist (mit Computern werden Probleme gelöst, welche man ohne Computer gar nicht hat). Das ist in beide Blickrichtungen des o.g. Gefälles gültig was auch impliziert das es noch handlicheres über C++ gibt. Alle möglichen "Zwischenformen" eines Computerprogrammes verlieren sowieso beim Relevanzvergleich (pun intended): es zählen letztlich nur die "niedrigste" Form für den ausführen Automaten und die dem die ursprüngliche Aufgabe lösenden Mensch behaglichste Form. Erstere Akteure haben nichts zu melden weil leblose Maschinen - letztere sind aus biologischer Evolution hervorgegangene komplexe Organismen wovon leider nicht alle Exemplare nur die besten Vorteile mit auf den Lebensweg abbekommen haben. In dieser Erbsenklauberei um den blossen Unterschied von "++" im Namen kann man schon merken wer sich mit Besitzstandwahrung begnügt und wer weder tief noch weit genug über seinen Tellerrand zu Blicken bereit/fähig ist.
Programmiersprachentheaterintendant schrieb: > Für alle 3 genannten Gruppen gilt: jeder darf bei seinem > Lieblingswerkzeug bleiben, ... ! unterschreib !
oh hallo Yalu, das Mikroskop für EBNF wieder beiseite gestellt? :-)
Programmiersprachentheaterintendant schrieb: > C-isten, welche C++-isten den nächsten "fürchterlichen" Schritt richtung > Hochsprache wegzetern wollen sollen bedenken dass sie selbst auf dem > gleichen Gefälle und in gleicher Position gegenüber ASM-isten sind. > Für alle 3 genannten Gruppen gilt: jeder darf bei seinem > Lieblingswerkzeug bleiben, solange es ihm gut von der Hand geht und egal > wie umständlich es tatsächlich ist (mit Computern werden Probleme > gelöst, welche man ohne Computer gar nicht hat). Das ist in beide > Blickrichtungen des o.g. Gefälles gültig was auch impliziert das es noch > handlicheres über C++ gibt. Ja, da hast Du sicherlich recht. Und bei den C++-isten führt das dann dazu, dass man sich eine eDSL in C++ selbst für seine Anwendungsdomäne erzeugt, die natürlich noch abstrakter als C++ selbst. Generische Algorithmen sind die Vorstufe, eine eDSL die nächste Stufe. Aber das machen ja auch die C-isten, z.B. mit Regulären-Ausdrücken, was einer DSL in etwa nahe kommt. Letztendlich geht es doch darum, wie schnell, sicher, effizient und dauerhaft ich als Mensch mit meinem Werkzeug ein Problem lösen kann. Natürlich muss das Ziel dabei sein, dass am Ende ein optimaler Code für die Maschine dabei heraus kommt.
Was mich bisher von C++ abgehalten hat, wurde durch den Beitrag von Beitrag "Re: Welche Programmiersprache auf µC" mehr als deutlich dargelegt. Allerdings für die kleinen µCs muss ich doch nicht den ganzen Wald kennen. Nur wie meine Perlen finden, ohne den gesamten Wald durchforsten zu müssen?
Johann L. schrieb: > Wilhelm M. schrieb: >> Johann L. schrieb: >>> Wilhelm M. schrieb: >>>> Allerdings ist beim avr-g++ die Libstdc++ nicht dabei (aus gutem Grund >>>> ;-) >>> >>> Und was ist dieser Grund? >>> >>> Du als C++ Hero wärst doch prädestiniert, den GCC so zu pimpen, dass er >>> auch C++ unterstützt. >> >> Was meinst Du? Tut er doch, der avr-g++. > > Nein, tut er nicht, denn zum C++ Standard gehören eben auch die > Standard-Bibliotheken, nicht nur der Sprachkern. > > Und den "guten Grund", warum dieser Teil von C++ nicht unterstützt wird, > kenn ich auch nicht. So weit ich das verstehe, beruht ein großer Teil der STL auf dem Vorhandensein von Exceptions. Ohne wäre es eine NonSTL. Allerdings gibt es es einige "statische" Dinge, z.B. std::array, die man kostenlos benutzen kann um Arrays konstanter Größe an <allgorithm> anzudocken. Man muß z.B. die Suche eines Maximalwerts in einem Int-Array nicht jedesmal neu erfinden. Stattdessen std::foreach über das Array und Lambda zu Verarbeitung der Werte.
Teo D. schrieb: > Nur wie meine Perlen finden, ohne den gesamten Wald durchforsten zu > müssen? Eigentlich nur, indem du überhaupt erstmal anfängst, dich damit zu befassen. Ich stand letztens auch vor rätselhaftem C++-Code (in qucs), bei dem ich erstmal Tante Gugel angeworfen habe. Offenbar versucht man in den letzten C++-Standards, FORTRAN nun mal die Domäne streitig zu machen, sie hätten für parallele Vektordatenverarbeitung die einzige nutzbare Programmiersprache, und hat solche Dinge jetzt in C++ drin. Allerdings genügte es mir für diesen Zweck vollauf, nur die Grundidee hinter den paar Zeilen zu verstehen (irgendwas musste da geändert werden, weiß nicht mehr genau, was es war). Solche Dinge muss ich gewiss nicht selbst schreiben können, erst recht nicht auf einem kleinen Controller.
Teo D. schrieb: > Nur wie meine Perlen finden, ohne den gesamten Wald durchforsten zu > müssen? Suche Steinpilze. Das ist im Wald aussichtsreicher. Abel
Beitrag #5042137 wurde von einem Moderator gelöscht.
Beitrag #5042153 wurde von einem Moderator gelöscht.
Beitrag #5042155 wurde von einem Moderator gelöscht.
Beitrag #5042158 wurde von einem Moderator gelöscht.
Beitrag #5042159 wurde von einem Moderator gelöscht.
Beitrag #5042160 wurde von einem Moderator gelöscht.
Es gibt allerdings ein ziemlich gewichtiges Argument für C: Es kam bei Star Wars zum Einsatz und zwar bei der Programmierung des Todessterns. Ich kann auch gerne die Quelle benennen :-)
Yalu X. schrieb: > Die C++-Konstanten sind i.Allg. schon etwas konstanter als diejenigen in > C, aber.. Muß ich jetzt mit dir schimpfen? Also, was man auf nem µC mit einem ordentlichen Compiler in C const macht, IST konstant. Und zwar derart konstant, daß es nicht konstanter geht. Hab grad mal das Menüsystem der steinalten Lernbetty (per Keil übersetzt) angeschaut: da ist schlichtweg ALLES im Flash. Sowohl die structs als auch die Texte als auch die Members in den structs und deren eben grad vorwärts deklarierten Zielen. Eben alles. konstanter geht es nicht mehr. W.S.
Programmiersprachentheaterintendant schrieb: > In dieser Erbsenklauberei um den blossen Unterschied > von "++" im Namen kann man schon merken wer sich mit Besitzstandwahrung > begnügt und wer weder tief noch weit genug über seinen Tellerrand zu > Blicken bereit/fähig ist. Ach, der Tellerrand. Ja, da hast du wohl Recht. So ziemlich alle hier in diesem Thread beteiligten scheinen einen recht kleinen Teller zu haben, der mal gerade von Assembler (schon außerhalb des Tellerrandes) über C und dann C++ bis Java und C# reicht. Mir ist dieser Teller zu klein, ich benutze dort wo ich kann, lieber Pascal und schreibe meine PC-Programme mit Delphi oder Lazarus. Aber bei den C-lastigen Leuten hier erwarte ich nicht, daß sie das aktuelle D10.2 Tokyo auch nur vom Hörensagen her kennen. Nur der Umstand, daß es keinen guten Pascal-Compiler für aktuelle µC gibt, führt dazu, für µC eben C zu verwenden. Aber auf die Idee, hier ein C++ verwenden zu wollen, halte ich für reinen Mutwillen. ach was.. gut Nacht zusammen! W.S.
W.S. schrieb: > Yalu X. schrieb: >> Die C++-Konstanten sind i.Allg. schon etwas konstanter als diejenigen in >> C, aber.. > > Muß ich jetzt mit dir schimpfen? Nein, musst du nicht. Es sei denn, du kannst nicht anders ;-) > Also, was man auf nem µC mit einem ordentlichen Compiler in C const > macht, IST konstant. Und zwar derart konstant, daß es nicht konstanter > geht. Mit konstant meine ich konstant im Sinn einer "constant expression" gemäß der C- und C++-Norm. Hätte ich konstant im mathematischen Sinn gemeint, hätte ich das Adjektiv nicht im Komparativ gebraucht.
W.S. schrieb: > Mir ist dieser Teller zu klein, ich benutze dort wo ich kann, lieber > Pascal und schreibe meine PC-Programme mit Delphi oder Lazarus. Also einfach einen anderen Teller. Auf die Argumente, dass dieser Teller auch nur golden aussieht und nicht aus Gold ist, gehst du sowieso nie ein, ist also auch egal. ;-) Viel mehr schade finde ich eigentlich, dass Ada in der Controllerwelt nie recht zum Fliegen gekommen ist. Der Zug ist aber halt einfach abgefahren, wie's scheint. Wenn die Controller größer werden, kann man sich dann wohl besser Gedanken um Lua oder Python machen, statt Ada oder Pascal nachzutrauern.
W.S. schrieb: > Also, was man auf nem µC mit einem ordentlichen Compiler in C const > macht, IST konstant. Und zwar derart konstant, daß es nicht konstanter > geht. > > Hab grad mal das Menüsystem der steinalten Lernbetty (per Keil > übersetzt) angeschaut: da ist schlichtweg ALLES im Flash. Wieso das denn? Was konstant ist, kennt der Compiler, das muss doch nicht ins Flash?
Beitrag #5042376 wurde von einem Moderator gelöscht.
Beitrag #5042378 wurde von einem Moderator gelöscht.
Jörg W. schrieb: > Wenn die Controller größer werden, kann man sich dann wohl besser > Gedanken um Lua oder Python machen, statt Ada oder Pascal nachzutrauern. Gedanken kann man sich machen und ein paar nette Spielereien sind damit sicher auch möglich aber dann hört es da meiner Meinung nach auch schon auf. Das einzige was noch einigermaßen erträglich vom Ressourcenverbrauch ist, ist wenn man vorhandene Funktionen, die in C implementiert sind per Scriptsprache mal eben schnell zu einem Programm zusammenhackt. Von der Performance abgesehen mag ich ganz prinzipiell kompilierte Sprachen, weil der Compiler mir gegebenenfalls schon auf die Finger haut bevor das Programm läuft. Aus dem Grund ziehe ich mittlerweile auf dem PC auch ein Go-Programm einem Python-Script vor. Die Programmierung ist ähnlich dynamisch wie bei Python und Go kompiliert dermaßen schnell das ein "go run some_program.go" gefühlt genauso schnell startet wie ein "./python_script.py". Das es zusätzlich noch um ein bis zwei Größenordnungen schneller läuft interessiert mich dabei meistens nicht mal, weil der Rechner für ein billiges Script bzw. Progrämmchen meist ohnehin mehr als genug Dampf hat. Da aber die aber die Mikrocontroller auch übermorgen nicht dutzende MB SRAM für lau mit an Board haben werden, wage ich mal zu behaupten, dass auch in zehn Jahren noch ASM, C und C++ vorherrschen werden (im Bereich uC). Eventuell wird sich noch Rust einen Teil vom Kuchen schnappen. Potential hat Rust meiner Meinung nach mehr als genug. Sehr starke Typisierung, quasi kein Runtime-Overhead und auch kein GC, trotzdem keine Dangling-Pointer und sonstige Zombies. Der Einstieg ist aber wirklich hart. Der Compiler haut einem anfangs so oft auf die Finger das es schnell weh tut. Wer da aus dem C(++)-Lager kommt verliert da schnell die Lust daran, weil nicht mehr alles erlaubt ist. Dafür hat man eine gewisse Sicherheit, dass das Programm sofern es denn kompiliert, frei von irgendwelchen Memorybugs ist.
Beitrag #5042385 wurde von einem Moderator gelöscht.
Beitrag #5042386 wurde von einem Moderator gelöscht.
Beitrag #5042388 wurde von einem Moderator gelöscht.
Beitrag #5042422 wurde von einem Moderator gelöscht.
Beitrag #5042423 wurde von einem Moderator gelöscht.
Beitrag #5042424 wurde von einem Moderator gelöscht.
Beitrag #5042447 wurde von einem Moderator gelöscht.
Christopher J. schrieb: > Jörg W. schrieb: >> Wenn die Controller größer werden, kann man sich dann wohl besser >> Gedanken um Lua oder Python machen, statt Ada oder Pascal nachzutrauern. > > Gedanken kann man sich machen und ein paar nette Spielereien sind damit > sicher auch möglich aber dann hört es da meiner Meinung nach auch schon > auf. Das einzige was noch einigermaßen erträglich vom > Ressourcenverbrauch ist, ist wenn man vorhandene Funktionen, die in C > implementiert sind per Scriptsprache mal eben schnell zu einem Programm > zusammenhackt. Ich hab leider mit Python und JS auf µC überhaupt keine Erfahrung, kenne aber zumindest Lua. Wenn ich ein Projekt vorgesetzt bekäme, dass weder Echtzeitfähigkeit benötigt, noch der Preis auf die letzte Kommastelle berücksichtigt werden muss, dann würde ich keine Sekunde zögern und irgendeine Skriptsprache verwenden. Gerade letzteres, sprich Lua, ist sogar begrenzt Echtzeitfähig, da die GC bei Bedarf deaktiviert werden kann...
Jörg W. schrieb: > Eigentlich nur, indem du überhaupt erstmal anfängst, dich damit zu > befassen. Danke, sehr nett von dir mir das zu unterstellen..... :´( Komm mal wieder runter! (und schneide dir mal wieder die Nasenhaare)
Vincent H. schrieb: > Ich hab leider mit Python und JS auf µC überhaupt keine Erfahrung, kenne > aber zumindest Lua. Wenn ich ein Projekt vorgesetzt bekäme, dass weder > Echtzeitfähigkeit benötigt, noch der Preis auf die letzte Kommastelle > berücksichtigt werden muss, dann würde ich keine Sekunde zögern und > irgendeine Skriptsprache verwenden. > Gerade letzteres, sprich Lua, ist sogar begrenzt Echtzeitfähig, da die > GC bei Bedarf deaktiviert werden kann... Ja, so waren damals auch meine Gedanken, als ich mir einen passenden Tcl-Interpreter für AVRs baute: für über 90% der Dinge, die ein µC macht, reicht eine Skriptsprache (sogar ohne Bytecompiler) vollkommen aus. Und da Speicher damals knapp war, konnte man so sehr große Programme z.B. in EEPROMs auslagern. Lua ähnelt Tcl von der Intention her stark (Einbau in C-Programme, Verlagerung der laufzeitunkritischen Dinge in die Skriptsprache, sehr einfache Implementierbarkeit weiterer C-Funktionen). Echtzeitfähigkeit kann man dort auch sehr einfach nachrüsten. Heutzutage passt der komplette Interpreter auf einen STM32 und wir sind dabei, Tk soweit zu portieren, dass man den Großteil der Tk-Befehle dann für eigene Oberflächen verwenden kann. Debugging gestaltet sich bei Skriptsprachen auch einfacher, weil man das Programm in einer Shell direkt auf dem Zielsystem ändern kann. Bei der Frage "Welche Programmiersprache auf µC" sollte man also durchaus auch einen interessierten Blick auf Skriptsprachen werfen.
Chris D. schrieb: > Bei der Frage "Welche Programmiersprache auf µC" sollte man also > durchaus auch einen interessierten Blick auf Skriptsprachen werfen. Wenn man diese Skriptspache erst selbst implementieren muss, dann dürfte das deren Attraktivitat etwas dämpfen...
Nur weil es damals so war, muss das nicht heute gelten :-) Es gibt durchaus einige sehr kleine Tcl-Interpreter: http://wiki.tcl.tk/1363 Bei Lua kenne ich mich nicht aus, aber eLua scheint in die Richtung zu gehen: http://www.eluaproject.net/
:
Bearbeitet durch Moderator
Beitrag #5042683 wurde von einem Moderator gelöscht.
Beitrag #5042687 wurde von einem Moderator gelöscht.
Beitrag #5042694 wurde von einem Moderator gelöscht.
Beitrag #5042695 wurde von einem Moderator gelöscht.
Jörg W. schrieb: > Teo D. schrieb: >> Nur wie meine Perlen finden, ohne den gesamten Wald durchforsten zu >> müssen? > > Eigentlich nur, indem du überhaupt erstmal anfängst, dich damit zu > befassen. OK, hab nun auch wieder Bodenkontakt ;) Hab mich vor ~25J mal damit befasst, daher auch der Bammel :) C++ Bücher gibt's ja zur genüge.... Leider alles nur Pfade durch den Dschungel. Ich würde mir gerne einen Überblick verschaffen, ohne ein Dutzend Bücher durchforsten zu müssen! Für die Grundlagen hab ich schon ein halbes Dutzend geordert. Wird schon was brauchbares dabei sein. :)
Beitrag #5042739 wurde von einem Moderator gelöscht.
Teo D. schrieb: > Hab mich vor ~25J mal damit befasst, daher auch der Bammel :) Irgendwann damals hatte ich auch mal einen C++-Lehrgang. Zum Glück nicht alles vergessen. ;-) Ich würde an deiner Stelle nicht zu viele Bücher wälzen, sondern mal kleine Stückchen programmieren. Wirklich erstmal die LED als Objekt. Vielleicht nach dem Ein- und Ausschalten dann auch mit einem PWM-Timer für die Helligkeitssteuerung erweitern. AVRs sind aufgrund ihrer IO-Registerstruktur nicht ganz so nett für eine Abstraktion in C++. Ich schrieb's oben schon mal, ein GPIO wird dort ja durch das Tupel {PORTx, PINx, DDRx} beschrieben, formal (wenn man nicht irgendwelche Mystik mit hin- und her-casten und händischen Offsets zwischen diesen Registern verzapfen möchte) muss man daher beim Konstruktor alle drei Namen übergeben. Wenn man nur „A“ oder „B“ (für das Metazeichen „x“ oben) schreiben will, dann hilft da leider wieder nur der leidige Präprozessor, denn er ist in der Lage, ganze Bezeichner durch Verkettung zu synthetisieren. Bei den Cortex-Ms ist das besser, da hat man sowas wie PORTx->DIR oder PORTx->DIN oder dergleichen; hier kann man das komplette „PORTx“ übergeben und damit den passenden Port wählen. Achso, und natürlich immer den generierten Assemblercode mit ansehen. Was sich übrigens gut macht ist, wenn man so viel wie möglich in der Abstraktion als „const“ bzw. „constexpr“ deklariert. Damit ist dann verbunden, dass man bei der Instanziierung keine Zuweisung machen darf, sondern den tatsächlichen Wert über den Konstruktor übergibt. Das wiederum gibt dem Compiler die Gewissheit, dass die Sache bereits zur Compilezeit bekannt ist, sodass er maximal die konstanten Dinge ersetzen kann. Auf dem AVR landet man so am Ende auch wieder bei CBI und SBI im generierten Code.
:
Bearbeitet durch Moderator
Beitrag #5042756 wurde von einem Moderator gelöscht.
Beitrag #5042770 wurde von einem Moderator gelöscht.
Beitrag #5042783 wurde vom Autor gelöscht.
Jörg W. schrieb: > Ich würde an deiner Stelle nicht zu viele Bücher wälzen, sondern mal > kleine Stückchen programmieren. Wirklich erstmal die LED als Objekt. > Vielleicht nach dem Ein- und Ausschalten dann auch mit einem > PWM-Timer für die Helligkeitssteuerung erweitern. Würdest du damit bitte aufhören! :) Jörg W. schrieb: > AVRs sind aufgrund ihrer IO-Registerstruktur nicht ganz so nett für > eine Abstraktion in C++........ Genau solch Informationen suche ich, kompakt und nicht auf Tausende Seiten verteilt..... Jörg W. schrieb: > Ich würde an deiner Stelle nicht zu viele Bücher wälzen Hab sie ja nur gekauft! Bei Bücherbillig für 20€. Gelesen wird nur was brauchbar ist. :)
Chris D. schrieb: > Bei der Frage "Welche Programmiersprache auf µC" sollte man also > durchaus auch einen interessierten Blick auf Skriptsprachen werfen. Ich entwickle gerade eine Interpretersprache NIC für 32-Bit-µCs. Die Entwicklung ist zur Zeit noch in der Alpha-Phase, jedoch zeigen erste Benchmarks, dass der Interpreter etwa doppelt so schnell wie PHP und 5-10 mal so schnell wie Python ist. Sobald ich eine Beta-Version fertig habe, werde ich sie unter "Projekte und Code" vorstellen. Die hohe Ausführungsgeschwindigkeit wird dadurch erreicht, dass der Host das NIC-Script vorcompiliert und dann auf den µC einen maschinenunabhängigen Objekt-Code hochlädt. Dabei werden dann auch direkt einige Optimierungen vorgenommen: Zum Beispiel werden konstante Ausdrücke in Expressions direkt zur Compilezeit ausgerechnet. Da die Übersetzungszeiten unter einer Sekunde bleiben, merkt man das überhaupt nicht. Sobald der Objekt-Code hochgeladen wurde, wird er auf dem µC (im Moment werden STM32F10x und STM32F4xx unterstützt) direkt ausgeführt. Dadurch verkürzt sich die Entwicklung eigener Programme, da das zeitaufwendige Flashen komplett entfällt. NIC-Programme laufen nicht nur auf den STM32, sondern auch unter Windows und Linux - auch wenn das nur ein Nebeneffekt ist. So kann ich den NIC-Compiler und NIC-Interpreter direkt auf dem Host testen. Fortgeschrittene Programmierer können die Sprache durch eigene C-Funktionen erweitern und diese dann direkt aus dem NIC-Programm aufrufen. So kann man zeitkritische Routinen in den C-Code verlagern. Im Moment ist die Sprache noch rein prozedural, Objekt-Orientierung wird aber noch kommen. Außerdem wird es noch einen weiteren Compiler geben, der den maschinenunabhängigen Objekt-Code in ein C-Programm umwandelt, um diesen dann zur NIC-Laufzeitbibliothek dazulinken zu können. Damit kann man dann nach der Entwicklungsphase das Programm mit annähernd der Geschwindigkeit laufen lassen, wie auch ein adäquates C-Programm brauchen würde. Ich habe auch schon mal begonnen, NIC zu dokumentieren. Diese Doku wird während der Entwicklung von mir parallel fortgeschrieben, siehe Artikel NIC.
:
Bearbeitet durch Moderator
Teo D. schrieb: > Genau solch Informationen suche ich, kompakt und nicht auf Tausende > Seiten verteilt..... Da es hier ja insgesamt um Sprachauswahl auf Mikrocontrollern geht, vielleicht dafür einen neuen Thread öffnen? Dieser hier ufert sowieso gerade aus.
Frank M. schrieb: > Chris D. schrieb: >> Bei der Frage "Welche Programmiersprache auf µC" sollte man also >> durchaus auch einen interessierten Blick auf Skriptsprachen werfen. > > Ich entwickle gerade eine Interpretersprache NIC für 32-Bit-µCs. Die > Entwicklung ist zur Zeit noch in der Alpha-Phase, jedoch zeigen erste > Benchmarks, dass der Interpreter etwa doppelt so schnell wie PHP und > 5-10 mal so schnell wie Python ist. Sobald ich eine Beta-Version fertig > habe, werde ich sie unter "Projekte und Code" vorstellen. Das klingt interessant, liest sich aber sehr wie Lua. Inwiefern wird sich NIC von Lua unterscheiden?
Wilhelm M. schrieb: > nicht angebrachten ... Exceptions Gerade Exceptions sind in kritischen Umgebungen toll, weil damit keine "vergessenen Returnwerte" passieren können, und man bei nicht abgefangen Exceptions einfach das ganze System in einen Fehlerzustand schicken kann. Ansonsten kann ich nur Bruce Douglass wiedergeben: meist nimmt man C, nicht weil es toll ist, sondern weil es funktioniert, überall verfügbar ist und wesentlich einfacher ist als C++. Bei größeren Projekten kann eine Teilmenge von C++ Sinn machen, wird aber tlw. von Zertifizierungsstellen nicht gern gesehen wegen mehr möglicher Dynamik (je nach verwendeten Features). Bzw. die Zertifizierer sehens nicht gern, ihre Chefs schon, weil die Anzahl der einzuwerfenden großen Scheine mit dem Zertifizierungsaufwand steigt.
vn n. schrieb: > Gerade Exceptions sind in kritischen Umgebungen toll, weil damit keine > "vergessenen Returnwerte" passieren können, und man bei nicht abgefangen > Exceptions einfach das ganze System in einen Fehlerzustand schicken > kann. Leider ist der Overhead nicht ganz zu verachten, den sie erzeugen. Daher mag man sie im Embedded-Bereich eher nicht. Ansonsten fänden sie wohl viele Programmierer gut.
> AVRs sind aufgrund ihrer IO-Registerstruktur nicht ganz so nett > für eine Abstraktion in C++. Offensichtlich hat auch Atmel das inzwischen erkannt und es bei der Xmega Serie besser gemacht. Für's Hobby sind die allerdings aus anderen Gründen weniger attraktiv.
Stefan U. schrieb: > Offensichtlich hat auch Atmel das inzwischen erkannt und es bei der > Xmega Serie besser gemacht. Ich denke nicht, das C++ dort das primäre Argument war :), aber ja, deren IO-Register sind diesbezüglich besser strukturiert. > Für's Hobby sind die allerdings aus anderen Gründen weniger attraktiv. Nicht nur da, auch anderweitig scheinen sie mir nicht so gut „ans Fliegen gekommen“ zu sein wie die klassischen AVRs. Verglichen mit der Konkurrenz aus dem Cortex-M-Lager waren sie dafür wohl einfach zu spät auf dem Markt.
Stefan U. schrieb: >> AVRs sind aufgrund ihrer IO-Registerstruktur nicht ganz so nett >> für eine Abstraktion in C++. > > Offensichtlich hat auch Atmel das inzwischen erkannt und es bei der > Xmega Serie besser gemacht. Für's Hobby sind die allerdings aus anderen > Gründen weniger attraktiv. Also wie die phys. I/O-Registeranornung aussieht, ist ziemlich egal. Man braucht ein bißchen template-Mechanik und gut ist. Das einzige, was sie bei den XMegas besser gemacht habe, dass sie schon die C structs definiert haben. Die muss man bei den non-XMega eben selbst erzeugen...
Bei den AVRs hat man vielleicht die IO-Register auf den Befehlssatz hin optimiert. Häufig bitweise zu Änderndes ganz nach vorn. Die XMegas haben aber so viele Register, daß der AVR-Ansatz eh nichts wird. Deshalb ist identischer Aufbau und instanzspezifische Basisadresse für die einzelnen Geräte sicher auch von Hardwareseite besser zu handhaben.
:
Bearbeitet durch User
Vincent H. schrieb: > Das klingt interessant, liest sich aber sehr wie Lua. Ich kannte Lua bisher nicht, habe es mir eben mal näher angeschaut. Ja, das sieht auf den ersten Blick tatsächlich sehr ähnlich aus :-) > Inwiefern wird sich NIC von Lua unterscheiden? Das kann ich jetzt noch nicht sagen, da ich Lua überhaupt nicht kenne. Ich werde mir Lua auf jeden Fall mal näher anschauen. Danke für den Hinweis. Ich habe mir eben mal Lua 5.2 unter Linux installiert und das im NIC-Artikel angeführte Benchmark-Programm "Sieb des Eratosthenes" von NIC auf Lua umgeschrieben, was gar nicht so viel Umstände bereitete. Ergebnis: Für die Ermittlung sämtlicher Primzahlen unter 100000 braucht NIC 5,3 Sekunden und Lua 6,1 Sekunden auf einem i7-2600@3.40GHz. Mit der um 20% höheren Geschwindigkeit bin ich ganz zufrieden, gerade weil NIC noch im Alpha-Stadium und als Interpreter trotzdem von der Ausführungszeit bisher noch ungeschlagen ist. Sobald der maschinenunabhägige Objekt-Code eines NIC-Programms in C übersetzt und damit echter Binärcode erzeugt werden kann, sollte noch ein weiterer Faktor von mindestens 10 drin sein. Die Lua-Variante vom Sieb-Programm werde ich dann im NIC-Artikel noch einfügen zum Vergleich. Wie ich schon sagte: Sobald eine Beta-Version von NIC verfügbar ist, werde ich das NIC-Projekt incl. Sources veröffentlichen.
:
Bearbeitet durch Moderator
Vincent H. schrieb: > Ich hab leider mit Python und JS auf µC überhaupt keine Erfahrung, kenne > aber zumindest Lua. Wenn ich ein Projekt vorgesetzt bekäme, dass weder > Echtzeitfähigkeit benötigt, noch der Preis auf die letzte Kommastelle > berücksichtigt werden muss, dann würde ich keine Sekunde zögern und > irgendeine Skriptsprache verwenden. > > Gerade letzteres, sprich Lua, ist sogar begrenzt Echtzeitfähig, da die > GC bei Bedarf deaktiviert werden kann... Ja, Lua ist meiner Meinung nach tatsächlich noch die brauchbarste Skriptsprache für Systeme mit begrenzten Ressourcen, weil vor allem auch die Anbindung an C sehr einfach ist. Schaut man da allerdings mal bei den üblichen Verdächtigen, wie z.B. http://nodemcu.com/ in den Source-Code, stellt man eben auch schnell fest, das im Prinzip alle "Low-Level" geschichten in C implementiert sind und man mit Lua lediglich "mal eben schnell" die einzelnen Bausteine zusammensetzt. Natürlich kann man Skripte vorab zu Bytecode kompilieren und das geht auch bei MicroPython aber wenn ich mein Programm ohnehin immer neu laden muss, dann kann ich das doch auch gleich in C++ schreiben (meinetwegen mit Arduino) und statt einer VM packe ich einfach einen Bootloader auf den uC der gegebenenfalls auch noch netzwerkfähig ist und wo ich über ein HTML-Interface eine neue Firmware laden kann, so wie das bei jedem Router typischerweise ist. Frank M. schrieb: > Ich entwickle gerade eine Interpretersprache NIC für 32-Bit-µCs. Sieht, wie ich finde, ebenenfalls sehr interessant aus. Jörg W. schrieb: > vn n. schrieb: >> Gerade Exceptions sind in kritischen Umgebungen toll, weil damit keine >> "vergessenen Returnwerte" passieren können, und man bei nicht abgefangen >> Exceptions einfach das ganze System in einen Fehlerzustand schicken >> kann. > > Leider ist der Overhead nicht ganz zu verachten, den sie erzeugen. > > Daher mag man sie im Embedded-Bereich eher nicht. Ansonsten fänden > sie wohl viele Programmierer gut. Auch wenn die Idee hinter den C++-Exceptions löblich sein mag, finde ich die Umsetzung eher suboptimal. Man hat seine Programmlogik und parallel dazu eine Exceptionlogik. Tritt ein Fehler auf, muss man aber erstmal wieder beides synchronisieren. Ich persönlich finde den Ansatz von Go oder Rust, die Fehlerbehandlung grundsätzlich über die Rückgabewerte der Funktionen (mittels "multiple return type") durchzuführen, wesentlich eleganter. Der Programmierer sollte sich eben schon in seiner Programmlogik Gedanken machen, an welcher Stelle etwas schief gehen kann und wie er das dann abfängt. In C gibt es ja die Hilfskrücke errno.h bzw. das überladen von Rückgabewerten (z.B. -1 für einen Fehler bei der Initialisierung eines Sockets). In der Praxis werden aber häufig nicht einmal diese Hilfskrücken genutzt und nach dem Motto "Et is noch immer jot jejange" einfach "void" als Rückgabewert gewählt. Demnach denke ich ist das grundsätzliche Problem eher die Grundeinstellung des Programmierers und erst nachrangig das es keine (vom Ressourcenverbrauch her) brauchbare Möglichkeit gibt Exceptions zu nutzen. Die "multiple return types" sind im Übrigen quasi ohne Overhead, weshalb man sie mit Rust auch z.B. auf einem Cortex-M problemlos nutzen kann. Hätte ich für C einen Wunsch für ein neues Feature frei und zur Wahl stünden C++-Exceptions und 'multiple return types', so würde ich eindeutig letzteres bevorzugen.
:
Bearbeitet durch User
Christopher J. schrieb: ... > Jörg W. schrieb: >> vn n. schrieb: >>> Gerade Exceptions sind in kritischen Umgebungen toll, weil damit keine >>> "vergessenen Returnwerte" passieren können, und man bei nicht abgefangen >>> Exceptions einfach das ganze System in einen Fehlerzustand schicken >>> kann. >> >> Leider ist der Overhead nicht ganz zu verachten, den sie erzeugen. >> >> Daher mag man sie im Embedded-Bereich eher nicht. Ansonsten fänden >> sie wohl viele Programmierer gut. ... > Hätte ich für > C einen Wunsch für ein neues Feature frei und zur Wahl stünden > C++-Exceptions und 'multiple return types', so würde ich eindeutig > letzteres bevorzugen. In "modernem" C++ werden Exceptions eigentlich kaum noch verwendet. Besser geeignet sind (v.a. dann auch im µC Bereich) std::optional oder ähnliche, konkrete Typen, die in ihrem Wertebereich einen ungültigen Wert haben.
Beitrag #5043573 wurde von einem Moderator gelöscht.
Beitrag #5043576 wurde von einem Moderator gelöscht.
Beitrag #5043577 wurde von einem Moderator gelöscht.
Beitrag #5043706 wurde von einem Moderator gelöscht.
Beitrag #5043707 wurde von einem Moderator gelöscht.
Beitrag #5043708 wurde von einem Moderator gelöscht.
Frank M. schrieb: > Ich habe auch schon mal begonnen, NIC zu dokumentieren. Diese Doku wird > während der Entwicklung von mir parallel fortgeschrieben, siehe Artikel > NIC. Nochmal vielen Dank für den Hinweis. Das sieht doch schon richtig gut aus. Ich werde allerdings bei Tcl bleiben, weil ich gerade die Typlosigkeit und Flexibilität (vor allem Listen, Arrays, neue Befehle/Umbenennung zur Laufzeit, Safe-Interpreter usw.) sehr schätze. Die GPIO-Funktionen habe ich dort schon implementiert ;-) Und dazu kommt natürlich (hoffentlich in Bälde) die Gui/Tk-Anbindung. Ich werde das aber auf jeden Fall im anderen Thread (Beitrag "NIC (aus dem langen C vs C++ Thread)") weiter beobachten.
Jörg W. schrieb: > vn n. schrieb: >> Gerade Exceptions sind in kritischen Umgebungen toll, weil damit keine >> "vergessenen Returnwerte" passieren können, und man bei nicht abgefangen >> Exceptions einfach das ganze System in einen Fehlerzustand schicken >> kann. > > Leider ist der Overhead nicht ganz zu verachten, den sie erzeugen. > > Daher mag man sie im Embedded-Bereich eher nicht. Ansonsten fänden > sie wohl viele Programmierer gut. Ok, vielleicht muss man der Vollständigkeit halber unterscheiden, ob man mit 8MHz oder 150MHz unterwegs ist. ;) Wilhelm M. schrieb: > In "modernem" C++ werden Exceptions eigentlich kaum noch verwendet. > Besser geeignet sind (v.a. dann auch im µC Bereich) std::optional oder > ähnliche, konkrete Typen, die in ihrem Wertebereich einen ungültigen > Wert haben. In kritischen Umgebungen können Exceptions halt den Vorteil haben, dass man sie nicht ignorieren kann (im Gegensatz zu return values).
vn n. schrieb: >> Leider ist der Overhead nicht ganz zu verachten, den sie erzeugen. >> Daher mag man sie im Embedded-Bereich eher nicht. Ansonsten fänden >> sie wohl viele Programmierer gut. > > Ok, vielleicht muss man der Vollständigkeit halber unterscheiden, ob man > mit 8MHz oder 150MHz unterwegs ist. ;) Ich denke, dass das gar nicht so sehr das Problem ist. Das letzte Mal, als ich mir das mal angesehen habe, war der Code Bloat, der von der Einbindung der Exceptions verursacht worden ist, aber immens. Damit ist es zumindest auf kleineren Controllern außen vor. Wenn man 1 MB Flash hat, mag die Sache anders aussehen.
Jörg W. schrieb: > vn n. schrieb: >>> Leider ist der Overhead nicht ganz zu verachten, den sie erzeugen. >>> Daher mag man sie im Embedded-Bereich eher nicht. Ansonsten fänden >>> sie wohl viele Programmierer gut. >> >> Ok, vielleicht muss man der Vollständigkeit halber unterscheiden, ob man >> mit 8MHz oder 150MHz unterwegs ist. ;) > > Ich denke, dass das gar nicht so sehr das Problem ist. Das letzte Mal, > als ich mir das mal angesehen habe, war der Code Bloat, der von der > Einbindung der Exceptions verursacht worden ist, aber immens. Damit > ist es zumindest auf kleineren Controllern außen vor. > > Wenn man 1 MB Flash hat, mag die Sache anders aussehen. Wenn man unbedingt Exceptions verwenden muss / möchte, aber deswegen ein Problem mit der Wartbarkeit / Lesbarkeit bekommt, könnte man auch über die sog. "Exploding-Return-Types" nachdenken.
Beitrag #5045091 wurde von einem Moderator gelöscht.
Beitrag #5045606 wurde von einem Moderator gelöscht.
Beitrag #5046556 wurde von einem Moderator gelöscht.
Beitrag #5047826 wurde von einem Moderator gelöscht.
Beitrag #5047832 wurde von einem Moderator gelöscht.
Beitrag #5048050 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Wenn man unbedingt Exceptions verwenden muss / möchte, aber deswegen ein > Problem mit der Wartbarkeit / Lesbarkeit bekommt, könnte man auch über > die sog. "Exploding-Return-Types" nachdenken. Wie groß ist eigentlich der Code Bloat, wenn man anstelle einer Exception-Instanz einen einfachen Integer-Fehlercode wirft (soetwas wie "throw 20;" statt "throw new RuntimeError("bla");")?
Sheeva P. schrieb: > Wilhelm M. schrieb: >> Wenn man unbedingt Exceptions verwenden muss / möchte, aber deswegen ein >> Problem mit der Wartbarkeit / Lesbarkeit bekommt, könnte man auch über >> die sog. "Exploding-Return-Types" nachdenken. > > Wie groß ist eigentlich der Code Bloat, wenn man anstelle einer > Exception-Instanz einen einfachen Integer-Fehlercode wirft (soetwas wie > "throw 20;" statt "throw new RuntimeError("bla");")? Das sollte man nicht machen, da der Compiler das Objekt, das geworfen wird (hier ein Zeiger) zerstört, aber nicht das Heap-Objekt: das müsste man im catch nun explizit zerstören. Deswegen niemals heap-allocated Objekte der Zeiger werfen. Oder SmartPtr. Aber die dyn. Allokation produziert natürlich viel Laufzeit-Overhead. Der Unterschied zwischen throw 20; und throw Bla; hängt davon ab, was der Ctor von Bla macht. Da ein Objekt immer (mindestens) ein Byte umfasst, ein int aber ggf. größer ist, könnte Bla günstiger sein. Aber wie gesagt: erstens: exceptions sind old-school und zweitens: auf Minimal-Systemen möchte man sie eh nicht ...
Wilhelm M. schrieb: > Sheeva P. schrieb: >> Wie groß ist eigentlich der Code Bloat, wenn man anstelle einer >> Exception-Instanz einen einfachen Integer-Fehlercode wirft (soetwas wie >> "throw 20;" statt "throw new RuntimeError("bla");")? > > Das sollte man nicht machen, da der Compiler das Objekt, das geworfen > wird (hier ein Zeiger) zerstört, aber nicht das Heap-Objekt: das müsste > man im catch nun explizit zerstören. Deswegen niemals heap-allocated > Objekte der Zeiger werfen. Oder SmartPtr. Aber die dyn. Allokation > produziert natürlich viel Laufzeit-Overhead. Schon klar, aber hier geht es ja um den besonderen Anwendungsfalls auf einem Mikrocontroller -- wo viele herkömmliche Empfehlungen nur teilweise oder gar nicht gelten. Und genau deswegen meine Frage: wie groß ist der Overhead in diesem speziellen Fall? > Aber wie gesagt: erstens: exceptions sind old-school und zweitens: auf > Minimal-Systemen möchte man sie eh nicht ... Exceptions sind IMHO keineswegs old-school, sondern ein ausgesprochen wert- und sinnvolles Instrument zur sauberen Behandlung von Fehlersituationen. Ob man sie auf Minimal-Systemen will oder nicht, hängt allerdings nicht zuletzt davon ab, wieviel Mehraufwand an Ressourcen sie produzieren...
Sheeva P. schrieb: > Wilhelm M. schrieb: >> Sheeva P. schrieb: >>> Wie groß ist eigentlich der Code Bloat, wenn man anstelle einer >>> Exception-Instanz einen einfachen Integer-Fehlercode wirft (soetwas wie >>> "throw 20;" statt "throw new RuntimeError("bla");")? >> >> Das sollte man nicht machen, da der Compiler das Objekt, das geworfen >> wird (hier ein Zeiger) zerstört, aber nicht das Heap-Objekt: das müsste >> man im catch nun explizit zerstören. Deswegen niemals heap-allocated >> Objekte der Zeiger werfen. Oder SmartPtr. Aber die dyn. Allokation >> produziert natürlich viel Laufzeit-Overhead. > > Schon klar, aber hier geht es ja um den besonderen Anwendungsfalls auf > einem Mikrocontroller -- wo viele herkömmliche Empfehlungen nur > teilweise oder gar nicht gelten. Und genau deswegen meine Frage: wie > groß ist der Overhead in diesem speziellen Fall? Schaus Dir an! Aber wie gesagt: per raw-Pointer ist extrem Fehlerträchtig, da expl. delete notwendig. >> Aber wie gesagt: erstens: exceptions sind old-school und zweitens: auf >> Minimal-Systemen möchte man sie eh nicht ... > > Exceptions sind IMHO keineswegs old-school, sondern ein ausgesprochen > wert- und sinnvolles Instrument zur sauberen Behandlung von > Fehlersituationen. Wie gesagt: std::optional oder splices oder exploding-return-types führen i.A. zu besserer Code-Struktur. > Ob man sie auf Minimal-Systemen will oder nicht, > hängt allerdings nicht zuletzt davon ab, wieviel Mehraufwand an > Ressourcen sie produzieren... Genau! Und da ist eine Exception auf dem Stack wesentlich leichtgewichtiger. Am besten als integral_constant<>, dann hat man alle Info im Typ und nicht als Wert und es reicht damit ein Byte!
Wilhelm M. schrieb: > Und da ist eine Exception auf dem Stack wesentlich leichtgewichtiger. Am > besten als integral_constant<>, dann hat man alle Info im Typ und nicht > als Wert und es reicht damit ein Byte! Vielleicht würdest du ja mal einen Wiki-Artikel hier im Wiki mit Codebeispielen für sowas anfangen? Das fände ich deutlich sinnvoller, als hier im Thread, denn wer diese Dinge noch nicht in den Fingern hatte, wird sich aus den paar Stichworten kaum einen Reim machen können. Vorschlag: C++ auf Mikrocontrollern
Jörg W. schrieb: > Vorschlag: C++ auf Mikrocontrollern Ja, das würde mich auch erfreuen. Ich habe hier gerade ein kleines Programm vor mir liegen. C++ ist der Standard im Arduino Umfeld. Da stellt sich die Frage "Welche Programmiersprache auf µC?" also eher nicht. In dem Programm werden ein paar Arduino Komfort Funktionen benutzt. z.B. ein 2 Sekunden delay() Und ein paar C++11 Features. Viel tut das Programm nicht: 6 Taster abfragen, und die zugeordnete LED leuchten lassen. Taste gedrückt, LED geht an. Taste losgelassen, die LED geht nach 1 Sekunde aus. Schickt man ein 'p' über die serielle Konsole, zeigt es die aktuelle Pin Zuordnung
1 | const unsigned long wartezeit = 1000; // leuchtdauer in ms |
2 | |
3 | struct LED : Printable |
4 | {
|
5 | byte taster; |
6 | byte led; |
7 | unsigned long startzeit; |
8 | |
9 | LED(byte taster, byte led):taster(taster),led(led){} |
10 | |
11 | void init() |
12 | {
|
13 | pinMode(led,OUTPUT); |
14 | digitalWrite(led,0); |
15 | pinMode(taster,INPUT_PULLUP); |
16 | }
|
17 | |
18 | void update() |
19 | {
|
20 | if(digitalRead(led) && millis()-startzeit>wartezeit) digitalWrite(led,0); |
21 | if(!digitalRead(taster)) // invers, wg. internem Pullup |
22 | {
|
23 | digitalWrite(led,1); |
24 | startzeit = millis(); |
25 | }
|
26 | }
|
27 | |
28 | size_t printTo(Print& p) const |
29 | {
|
30 | int len = 0; |
31 | len+=p.print(F("TasterPin: ")); |
32 | len+=p.print(taster); |
33 | len+=p.print(F(" LedPin: ")); |
34 | len+=p.print(led); |
35 | len+=p.print(F(" Startzeit: ")); |
36 | len+=p.println(startzeit); |
37 | return len; |
38 | }
|
39 | |
40 | };
|
41 | |
42 | LED ledGruppe[] |
43 | {
|
44 | // {tasterpin,ledpin},
|
45 | {A0,13}, |
46 | { 2,12}, |
47 | { 3,11}, |
48 | { 4,10}, |
49 | { 5, 9}, |
50 | { 6, 8}, |
51 | };
|
52 | |
53 | void serialEvent() |
54 | {
|
55 | while(Serial.available()) |
56 | {
|
57 | if('p' == Serial.read()) |
58 | {
|
59 | for(auto && i :ledGruppe) Serial.print(i); |
60 | Serial.println(); |
61 | }
|
62 | }
|
63 | }
|
64 | |
65 | void yield() |
66 | {
|
67 | for(auto && i :ledGruppe) i.update(); |
68 | }
|
69 | |
70 | void setup() |
71 | {
|
72 | Serial.begin(9600); |
73 | for(auto && i :ledGruppe) i.init(); |
74 | }
|
75 | |
76 | void loop() |
77 | {
|
78 | // nur alle 2 Sekunden auf die serielle Schnittstelle reagieren
|
79 | delay(2000); |
80 | }
|
Kompiliert mit der Arduino IDE und getestet auf einem UNO So, und jetzt möge die ArduinoHasserFraktion über mich herfallen....
Arduino F. schrieb: > Jörg W. schrieb: >> Vorschlag: C++ auf Mikrocontrollern > Ja, das würde mich auch erfreuen. > > Ich habe hier gerade ein kleines Programm vor mir liegen. > C++ ist der Standard im Arduino Umfeld. > Da stellt sich die Frage "Welche Programmiersprache auf µC?" also eher > nicht. Wenn Du Vergleichbarkeit mit anderen Realisierungen herstellen möchtest, wäre es gut wenn Du die Ausgabe von
1 | $ avr-nm -SCn -t d xxx.elf |
oder
1 | $ avr-size xxx.elf |
hier posten würdest und auch sagen würdest, welcher µC das ist. Denn viele werden dieses Beispiel nicht nachvollziehen können / wollen, weil sie (wie ich) Arduino agnostisch sind ...
Da will ich doch gerne drauf antworten Wilhelm M. schrieb: > Wenn Du Vergleichbarkeit mit anderen Realisierungen herstellen möchtest, Möchte ich eigentlich nicht.... war zumindest nicht Ziel Das Beispiel soll kein RessourcenSparWunder sein. Wilhelm M. schrieb: > sagen würdest, welcher µC Mit "Getestet auf einem Arduino UNO" ist der ATMega328P gemeint. Wilhelm M. schrieb: > oder > $ avr-size xxx.elf Du meinst sowas?:
1 | Der Sketch verwendet 2.930 Bytes (9%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes. |
2 | Globale Variablen verwenden 240 Bytes (11%) des dynamischen Speichers, 1.808 Bytes für lokale Variablen verbleiben. |
Die IDE nutzt intern avr-size. 128 Byte Ram gehen alleine für die Serial FiFos drauf
Arduino F. schrieb: > Wilhelm M. schrieb: >> Wenn Du Vergleichbarkeit mit anderen Realisierungen herstellen möchtest, > Möchte ich eigentlich nicht.... war zumindest nicht Ziel Ok, allerdings war das ja eigentlich das Kernthema hier. > Du meinst sowas?: ... ja >
1 | > Der Sketch verwendet 2.930 Bytes (9%) des Programmspeicherplatzes. Das |
2 | > Maximum sind 32.256 Bytes. |
3 | > Globale Variablen verwenden 240 Bytes (11%) des dynamischen Speichers, |
4 | > 1.808 Bytes für lokale Variablen verbleiben. |
> Die IDE nutzt intern avr-size. Das ist natürlich schon mal amtlich! > 128 Byte Ram gehen alleine für die Serial FiFos drauf Und wo bleiben dann die anderen 112 Bytes? Evtl. könntest Du die Zeile
1 | for(auto && i :ledGruppe) Serial.print(i); |
testweise auskommentieren und nochmal die Größenangaben nennen (nur für den Spaß ;-))
Aber gerne doch... Alles, was mit Serial zu tun hat, rausgeworfen.
1 | Der Sketch verwendet 1.414 Bytes (4%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes. |
2 | Globale Variablen verwenden 45 Bytes (2%) des dynamischen Speichers, 2.003 Bytes für lokale Variablen verbleiben. |
// ----------------- Wenn es sich um weitere Optimierung dreht, müssten die andern Arduino Komfort Dinger auch noch raus fliegen. digitalRead() und seine Kumpanen, sind auch relativ fett. Nicht nur die Funktionen an sich, sondern auch die Aufdröseltabellen(+Funktionen), welche diese brauchen, um von der Pinnummer auf die IO Register zu schließen. Ein leerer Rumpf:
1 | int main(void ) |
2 | {
|
3 | for(;;); |
4 | return 0; |
5 | }
|
Sagt:
1 | Der Sketch verwendet 134 Bytes (0%) des Programmspeicherplatzes. Das Maximum sind 32.256 Bytes. |
2 | Globale Variablen verwenden 0 Bytes (0%) des dynamischen Speichers, 2.048 Bytes für lokale Variablen verbleiben. |
Das Kompilat besteht dann quasi nur noch aus Interruptsprungleiste,
Stack Initialisierung und leerer main().
Es ist also möglich den Komfort komplett zu entfernen.
In der Regel zieht aber das Argument:
Für ungenutzten Speicher gibts kein Geld zurück.
// ------------- Nachtrag:
> Evtl. könntest Du die Zeile
Das bringt nicht viel, 40 Byte Flash Einsparung.
Beitrag #5051474 wurde von einem Moderator gelöscht.
Arduino F. schrieb: > Es ist also möglich den Komfort komplett zu entfernen. Wenn du auf setup() und loop() verzichtest und stattdessen dein eigenes main() baust, hast du aber effektiv keinen Arduino mehr. Dann sind Aussagen darüber witzlos.
Beitrag #5051970 wurde von einem Moderator gelöscht.
S. R. schrieb: > Arduino F. schrieb: >> Es ist also möglich den Komfort komplett zu entfernen. > > Wenn du auf setup() und loop() verzichtest und stattdessen dein eigenes > main() baust, hast du aber effektiv keinen Arduino mehr. Dann sind > Aussagen darüber witzlos. Na, na... Es ist, und bleibt, weiterhin eine C++ Umgebung. Dass die mitgelieferten Arduino Funktionen keine Performance Wunder sind, ist nicht erst seit heute klar. Die ansonsten positiven/willkommenen Eigenschaften, wie Wiederverwendbarkeit und Plattformneutralität(im Arduino Zoo), müssen der Performance geopfert werden, wenn es denn nötig ist. Das ist keine so ganz unübliche Strategie. Findet man auch woanders.
Arduino F. schrieb: > Es ist, und bleibt, weiterhin eine C++ Umgebung. Ja, aber keine Arduino-Umgebung mehr. Wenn du in einem "Auto-vs-Fahrrad"-Vergleich deinen Golf nimmst und Motor, Getriebe, Türen, Scheiben, ... entfernst, dann hast du am Ende vielleicht etwas, was mit einem Fahrrad theoretisch vergleichbar ist. Aber es ist definitiv kein Auto mehr, oder zumindest für den Vergleich vollkommen untauglich. Leere Firmwares sollten in C und C++ identisch sein. Interessant ist, wie hoch der Preis für "Arduino" ist, wenn man zwei vergleichbare Programme benutzt. Ob es sich im Einzelfall lohnt, muss jeder mit sich selbst ausmachen - wie bei printf und Freunden auch. Ein guter Vergleich - aus meiner Sicht - wäre dein Programm in vier Varianten: - "Arduino" - "Arduino mit Abkürzungen" (also ohne digitalWrite / Serial) - "C++" (aber mit der gleichen Struktur) - "C" (als Vergleichsbasis)
S. R. schrieb: > - "Arduino mit Abkürzungen" (also ohne digitalWrite / Serial) Den Punkt kannst du beruhigt streichen, denn das ist dann, laut deiner eigenen Aussage, kein Arduino mehr.
S. R. schrieb: > Wenn du auf setup() und loop() verzichtest und stattdessen dein eigenes > main() baust, hast du aber effektiv keinen Arduino mehr. Ich komme auf die gleiche Größe mit setup() und loop(). Die machen das Kraut also nicht fett. ;-)
Arduino F. schrieb: > S. R. schrieb: >> - "Arduino mit Abkürzungen" (also ohne digitalWrite / Serial) > Den Punkt kannst du beruhigt streichen, denn das ist dann, laut deiner > eigenen Aussage, kein Arduino mehr. Da wolltest du mich dann absichtlich missverstehen. Aber gut, belassen wir's dabei, ich muss keine Haare spalten. Jörg W. schrieb: > Ich komme auf die gleiche Größe mit setup() und loop(). Die machen > das Kraut also nicht fett. ;-) Danke für den Test. ;-)
S. R. schrieb: > Ein guter Vergleich - aus meiner Sicht - wäre dein Programm in vier > Varianten: > - "Arduino" > - "Arduino mit Abkürzungen" (also ohne digitalWrite / Serial) > - "C++" (aber mit der gleichen Struktur) > - "C" (als Vergleichsbasis) hier fehlt dann auch noch Assembler.
Wilhelm M. schrieb: > hier fehlt dann auch noch Assembler. Dann wirds aber auch schon enger, mit der Arduino IDE. Das kann sie nur als inline Assembler, oder als *.S in Libs
Wilhelm M. schrieb: > hier fehlt dann auch noch Assembler. Assembler habe ich absichtlich weggelassen, weil das kein sinnvoller Vergleich wird, sondern nur sinnbefreites Trollfutter.
S. R. schrieb: > Wilhelm M. schrieb: >> hier fehlt dann auch noch Assembler. > > Assembler habe ich absichtlich weggelassen, weil das kein sinnvoller > Vergleich wird, sondern nur sinnbefreites Trollfutter. Mmh, wenn die Anforderungen an den Vergleich klar sind, sehe ich das eigentlich nicht als "Trollfutter": man müsste mindestens noch hinzufügen, dass wir einen ms-genauen Systemtick haben wollen und einen UART mit jeweils x-Byte send/recv-Queue.
Und was bringt so ein Vergleich? Wenn die Aufgabe mit der gewünschten Hard- und Software gelöst wurde und alle Anforderungen erfüllt sind ist das Problem doch gelöst. Die LED Klasse ist wiederwendbar, im main wo es um die reine Applikation geht muss ich mich nicht durch LowLevel Initialisierungen kämpfen, wenn mehr LED/Taster nötig werden ist lediglich die Tabelle zu erweitern, alles gut finde ich.
Arduino F. schrieb: > In der Regel zieht aber das Argument: > Für ungenutzten Speicher gibts kein Geld zurück. Sehe ich mittlerweile privat genau so. Ich kenne zwar einige Schrauben zum justieren des Speicherverbrauchs, aber eine schöne C++-HAL ist mir die "Verschwendung" durchaus wert. Ich nehme gerne Interfaces (abstrakte Klassen) her, was natürlich RAM verbrät für die vtables, aber diese Art so zu coden gefällt mir richtig gut und da nehme ich das gerne in Kauf. Wobei ich die Tage ehrlich gesagt schon arg mit mir kämpfen musste: Ich stand ganz kurz davor aus RAM-spargründen virtuelle Methode aus einem Interface zu verbannen, die durchaus nützlich, jedoch nicht notwendig waren. Aber die Bequemlichkeit in der Benutzung hat gesiegt ;). Es bleibt jetzt so wie es ist. Mal ganz ehrlich - wann schafft man es schon wirklich mal einen Atmega238P zu füllen? Der reicht für kleinere Steuerungsaufgaben doch sehr oft aus und Arduino bringt den auch nicht so schnell voll. Zur Not müsste man dann halt ein STM32-CM3 oder ähnliches hernehmen. Wenn man natürlich auch privat den Anspruch hat immer auf alle Ressourcen zu achten (die Phase hatte ich sehr lange), dann wird man mit so etwas wie Arduino nicht glücklich. ;) Grüße Oliver
Langsam kristallisiert sich prinzipiell die folgende Tatsache heraus: Jeder soll eben auf seine Art selig werden und wie er seine Projekte nach besten Wissen und Können durchzieht. Ich finde, diese ganze Diskussion bringt wenig. Ganz abgesehen davon, wer mit einer Mikroprozessor/uC umgehen kann, sollte sehr wenig Mühe haben mit anderen umzugehen. Wenn man mit einer Programmiersprache gut umzugehen weiß, findet immer Lösungen seiner Probleme. Manchmal kommt mir vor man bewertet zu viele Programmiersprachen nach ihren *exappeal;-) Wenn man ehrlich ist, reicht für die alltäglichen Steueraufgabenprojekte auch der etwas bescheidene 328P und wer mehr Leistung und Platz braucht dem stehen genug Pfade zum Leistungsanstieg zur Auswahl. Für viele Anwendung ist es mir sowieso ziemlich gleichgültig auf welchen uC ich meine Projekte durchziehe. Solange der notwendige Funktionsumfang gegeben ist, spielen die alle ihre Liedchen. Das war mein Freitagsbeitrag, Schönes Wochenende! P.S. Zeit einen Radausflug bei dem schönen Wetter zu machen anstatt im Labor zu verkümmern und wunderlich zu werden...
Oliver J. schrieb: > Arduino F. schrieb: >> In der Regel zieht aber das Argument: >> Für ungenutzten Speicher gibts kein Geld zurück. > > Sehe ich mittlerweile privat genau so. Ich kenne zwar einige Schrauben > zum justieren des Speicherverbrauchs, aber eine schöne C++-HAL ist mir > die "Verschwendung" durchaus wert. Das hat weniger etwas mit privat vs. professionel zu tun. Sondern eher etwas mit den Stückzahlen. Auch ein "Profi" wird bei kleinen Stückzahlen versuchen, die Entwicklungszeiten zu reduzieren. Eine "schöne" HAL würde aber auch keine Resourcen verschwenden. Darum geht es doch die ganze Zeit in dieser Diskusion: In C++ kannst Du Abstraktionen ohne Overhead schaffen! > Ich nehme gerne Interfaces (abstrakte > Klassen) her, was natürlich RAM verbrät für die vtables, aber diese Art > so zu coden gefällt mir richtig gut und da nehme ich das gerne in Kauf. Das ist Quatsch (mit Verlaub): die vtables sollten im ROM liegen, wenn Deine tool chain nicht kaput ist. Im RAM liegt maximal ein Zeiger auf den Anfang der Tabelle. Aber was willst Du mit Laufzeitpolymorphy, wenn in Deiner Applikation die Konfiguration statisch ist? > Wobei ich die Tage ehrlich gesagt schon arg mit mir kämpfen musste: Ich > stand ganz kurz davor aus RAM-spargründen virtuelle Methode aus einem > Interface zu verbannen, die durchaus nützlich, jedoch nicht notwendig > waren. Aber die Bequemlichkeit in der Benutzung hat gesiegt ;). Es > bleibt jetzt so wie es ist. Und, hast Du Dir den das Map-File mal genauer angeguckt, bevor Du mit Deinen Überlegungen angefangen hattest? mfg Torsten
Beitrag #5052732 wurde von einem Moderator gelöscht.
Torsten R. schrieb: > Das ist Quatsch (mit Verlaub): die vtables sollten im ROM liegen, wenn > Deine tool chain nicht kaput ist. Im RAM liegt maximal ein Zeiger auf > den Anfang der Tabelle. Kein Grund unhöflich werden. Das handhabt der avr-g++ meines Wissens so. Da kann ich nichts dafür. Liegt wahrscheinlich an der PROGMEM-Problematik. Aber ist mir eigentlich auch egal, denn die paar Bytes stören mich ehrlich gesagt nicht wirklich solange ich noch genug Reserven hab. P.S. das Teil hier schaut ganz interessant aus. Sollte ich mir wahrscheinlich mal ansehen: https://github.com/jcmvbkbc/avr-flash-vtbl Torsten R. schrieb: > Aber was willst Du mit Laufzeitpolymorphy, wenn > in Deiner Applikation die Konfiguration statisch ist? So erzeuge ich halt Code. Mir ist leider keine Art bekannt z.b. ein Proxy-Pattern oder überhaupt Interfaces ohne so etwas komfortabel umsetzen. Dir? Torsten R. schrieb: > Das hat weniger etwas mit privat vs. professionel zu tun. Sondern eher > etwas mit den Stückzahlen. Auch ein "Profi" wird bei kleinen Stückzahlen > versuchen, die Entwicklungszeiten zu reduzieren. Stimmt. Dachte das wäre jedem hier klar und hab mir die Passage im Post deshalb geschenkt. Torsten R. schrieb: > Und, hast Du Dir den das Map-File mal genauer angeguckt, bevor Du mit > Deinen Überlegungen angefangen hattest? Ja das hab ich. Ich hab mir sogar die vtables angesehen. Torsten R. schrieb: > Eine "schöne" HAL würde aber auch keine Resourcen verschwenden. Darum > geht es doch die ganze Zeit in dieser Diskusion: In C++ kannst Du > Abstraktionen ohne Overhead schaffen! Das geht natürlich, aber wozu sollte ich das tun, wenn ich die Anforderung nicht habe? P.S. Schätze mein ironisch gewählter Nickname hat wohl ein falsches Bild von mir vermittelt. Dafür muss ich mich dann wohl bei Dir entschuldigen. :D Grüße Oliver
Torsten R. schrieb: > Das ist Quatsch (mit Verlaub): die vtables sollten im ROM liegen, > wenn Deine tool chain nicht kaput ist. G++ legt VTables nach .rodata, und .rodata wird vei avr-gcc/++ (außer für avrtiny und avrxmega3) ins RAM lokatiert. Grund ist, dass bei avr-g++ und
1 | char lese (const char *c) |
2 | {
|
3 | return *c; |
4 | }
|
nichts über die Ablage bekannt ist, und Lesen aus dem Flash andere Instruktionen erfordert als Lesen aus dem RAM. Weil man nicht wirklich zur Laufzeit entscheiden will (und noch nichteinmal kann) liegt das Zeug im RAM. Und VTables brachen nicht nur Platz sondern sind bei Verwendung auch langsamer.
:
Bearbeitet durch User
Johann L. schrieb: > Und VTables brachen nicht nur Platz sondern sind bei Verwendung auch > langsamer. Das stimmt natürlich. Es muss ja immer erst über die die Adresse der Vtable und dem jeweiligen Offset die Methoden-Adresse geholt werden, bevor man reinspringen kann. Für hochfrequente Aufrufe wäre die Verwendung von virtuellen Methoden somit eher kontraproduktiv. Da verzichte ich natürlich drauf. Grüße Oliver
Arduino F. schrieb: > Aber gerne doch... > > Alles, was mit Serial zu tun hat, rausgeworfen. >
1 | > Der Sketch verwendet 1.414 Bytes (4%) des Programmspeicherplatzes. Das |
2 | > Maximum sind 32.256 Bytes. |
3 | > Globale Variablen verwenden 45 Bytes (2%) des dynamischen Speichers, |
4 | > 2.003 Bytes für lokale Variablen verbleiben. |
5 | > |
> > // ----------------- Vorher waren es 240 Bytes Ram, nun (ohne die UART-Instanz) 45 Bytes. Also 195 Bytes für ein UART-Objekt mit 2x64-Byte FiFos. Also irgendwo bleibt da ja recht viel auf der Strecke ... auch die 6 Led-Instanzen sind 36 Bytes. > Wenn es sich um weitere Optimierung dreht, müssten die andern Arduino > Komfort Dinger auch noch raus fliegen. Auf keinen Fall. Es geht doch nicht darum, auf Komfort zu verzichten. Ganz im Gegenteil: ich will allen Komfort den ich bekommen kann - allerdings will ich dafür "nichts bezahlen". Und m.E. muss man dafür auch nichts bezahlen. Allerdings braucht es dafür auch die Bereitschaft, von manchem Standardvorgehen abzuweichen. In Deinem Arduino Beispiel und generell ist es z.B. vollkommen unnötigt, die Information über den Pin der Led oder des Tasters im RAM abzulegen. Das ist eine statische Information, die in den Typ codiert werden sollte. Typ-Information benötigen keinen zusätzlichen Speicher. Und ja: ich kann mit Typen auch "rechnen" : das nennt sich dann Meta-Funktion. Bei solchen Anwendungen erlebt TMP eine gewisse Renaissance. > digitalRead() und seine Kumpanen, sind auch relativ fett. Nicht nur die > Funktionen an sich, sondern auch die Aufdröseltabellen(+Funktionen), > welche diese brauchen, um von der Pinnummer auf die IO Register zu > schließen. Das kann der Compiler alles zur Compilezeit ausrechnen, dafür habe ich ja einen Compiler! Und nicht zur Laufzeit: das kosten RAM und CPU-Zyklen. > Ein leerer Rumpf: >
1 | >
|
2 | > int main(void ) |
3 | > { |
4 | > for(;;); |
5 | > return 0; |
6 | > } |
7 | >
|
> Sagt: >
1 | > Der Sketch verwendet 134 Bytes (0%) des Programmspeicherplatzes. Das |
2 | > Maximum sind 32.256 Bytes. |
3 | > Globale Variablen verwenden 0 Bytes (0%) des dynamischen Speichers, |
4 | > 2.048 Bytes für lokale Variablen verbleiben. |
Jo, das ist normal. > Es ist also möglich den Komfort komplett zu entfernen. s.o., auf keinen Fall. > In der Regel zieht aber das Argument: > Für ungenutzten Speicher gibts kein Geld zurück. Stimmt, meistens kostet es dann beim nächsten Update viel ... ;-)
Arduino F. schrieb: > Aber gerne doch... > > Alles, was mit Serial zu tun hat, rausgeworfen. >
1 | > Der Sketch verwendet 1.414 Bytes (4%) des Programmspeicherplatzes. Das |
2 | > Maximum sind 32.256 Bytes. |
3 | > Globale Variablen verwenden 45 Bytes (2%) des dynamischen Speichers, |
4 | > 2.003 Bytes für lokale Variablen verbleiben. |
5 | > |
> > // ----------------- Vorher waren es 240 Bytes Ram, nun (ohne die UART-Instanz) 45 Bytes. Also 195 Bytes für ein UART-Objekt mit 2x64-Byte FiFos. Also irgendwo bleibt da ja recht viel auf der Strecke ... auch die 6 Led-Instanzen sind 36 Bytes. > Wenn es sich um weitere Optimierung dreht, müssten die andern Arduino > Komfort Dinger auch noch raus fliegen. Auf keinen Fall. Es geht doch nicht darum, auf Komfort zu verzichten. Ganz im Gegenteil: ich will allen Komfort den ich bekommen kann - allerdings will ich dafür "nichts bezahlen". In Deinem Arduino Beispiel und generell ist es z.B. vollkommen unnötigt, die Information über den Pin der Led oder des Tasters im RAM abzulegen. Das ist eine statische Information, die in den Typ codiert werden sollte. Typ-Information benötigen keinen zusätzlichen Speicher. Und ja: ich kann mit Typen auch "rechnen" : das nennt sich dann Meta-Funktion. Bei solchen Anwendungen erlebt TMP eine gewisse Renaissance. > digitalRead() und seine Kumpanen, sind auch relativ fett. Nicht nur die > Funktionen an sich, sondern auch die Aufdröseltabellen(+Funktionen), > welche diese brauchen, um von der Pinnummer auf die IO Register zu > schließen. Das kann der Compiler alles zur Compilezeit ausrechnen, dafür habe ich ja einen Compiler! Und nicht zur Laufzeit: das kosten RAM und CPU-Zyklen. > Ein leerer Rumpf: >
1 | >
|
2 | > int main(void ) |
3 | > { |
4 | > for(;;); |
5 | > return 0; |
6 | > } |
7 | >
|
> Sagt: >
1 | > Der Sketch verwendet 134 Bytes (0%) des Programmspeicherplatzes. Das |
2 | > Maximum sind 32.256 Bytes. |
3 | > Globale Variablen verwenden 0 Bytes (0%) des dynamischen Speichers, |
4 | > 2.048 Bytes für lokale Variablen verbleiben. |
Jo, das ist normal. > Es ist also möglich den Komfort komplett zu entfernen. s.o., auf keinen Fall. > In der Regel zieht aber das Argument: > Für ungenutzten Speicher gibts kein Geld zurück. Stimmt, meistens kostet es dann beim nächsten Update viel ... ;-)
Oliver J. schrieb: > Johann L. schrieb: >> Und VTables brachen nicht nur Platz sondern sind bei Verwendung auch >> langsamer. > Das stimmt natürlich. Es muss ja immer erst über die die Adresse der > Vtable und dem jeweiligen Offset die Methoden-Adresse geholt werden, > bevor man reinspringen kann. Für hochfrequente Aufrufe wäre die > Verwendung von virtuellen Methoden somit eher kontraproduktiv. Da > verzichte ich natürlich drauf. > > Grüße Oliver Ich würde erst mal nachschauen, ob der GCC nicht selber gemerkt hat, daß es sich um Scheinvirtualirät handelt. Der hat nämlich einen "Devirtualizer". Man sollte ein virtuell formuliertes, von einem tatsächlich virtuellen Problem unterscheiden. So wie eine mit diversen variadic Templates gebaute GPIO Lib durchaus ein
1 | using Led = Avr::GpioBit<Avr::PortB,3,Avr::PinMode::Inverted>; |
2 | Led::Set(); |
zu
1 | CBI 0x05,3 |
werden kann.
Carl D. schrieb: > Ich würde erst mal nachschauen, ob der GCC nicht selber gemerkt hat, daß > es sich um Scheinvirtualirät handelt. Der hat nämlich einen > "Devirtualizer". Man sollte ein virtuell formuliertes, von einem > tatsächlich virtuellen Problem unterscheiden. Danke Dir. Das ist ein sehr guter Punkt. Den Compilerschalter '-fdevirtualize' kannte ich bisher noch nicht. Jedoch bringt er in meinem Fall leider keine Besserung. Edit: Es wurden definitiv vtables für folgende Verebungshierachien erzrugt: Interface <- abstrakte Basisklasse <- n verschiedene Implementierungen Interface <- ProxyKlasse Grüße Oliver
:
Bearbeitet durch User
Carl D. schrieb: > So wie eine mit diversen variadic Templates gebaute GPIO Lib durchaus > ein >
1 | using Led = Avr::GpioBit<Avr::PortB,3,Avr::PinMode::Inverted>; |
2 | > Led::Set(); |
> zu >
1 | CBI 0x05,3 |
> werden kann.
Falsch: werden muss!
Wenn nicht, dann hat man etwas beim Design der Template-Bibliothek
massiv(!) falsch gemacht.
Wilhelm M. schrieb: > Carl D. schrieb: > >> So wie eine mit diversen variadic Templates gebaute GPIO Lib durchaus >> ein >>
1 | using Led = Avr::GpioBit<Avr::PortB,3,Avr::PinMode::Inverted>; |
2 | >> Led::Set(); |
>> zu >>
1 | CBI 0x05,3 |
>> werden kann. > > Falsch: werden muss! > Wenn nicht, dann hat man etwas beim Design der Template-Bibliothek > massiv(!) falsch gemacht. Keine Frage, nur wird ja oft behauptet "niemals werden kann" und wenn man die Arduino-Variante anschaut, dann versteht man warum.
In meinen Augen hat auch die ArduinoVariante (damit meine ich das ganze Framework) durchaus ihre Daseinsberechtigung, gerade für die Zeilgruppe der Platform. Ich kann mir irgendwie nicht vorstellen, das sich eine Templateumsetzung genau so einfach handhabt. Kann mich aber natürlich auch täuschen. Wobei wie schon gesagt die Arduinovariante ganz klar verliert, wenn man nichts zu verschenken hat. Hier haben sich ein paar Leute mal zur Problematik "C++ Interface vs. Template" ausgelassen. Finde ich ziemlich interessant: https://stackoverflow.com/questions/16586489/c-interface-vs-template Grüße Oliver
:
Bearbeitet durch User
Oliver J. schrieb: > In meinen Augen hat auch die ArduinoVariante (damit meine ich das ganze > Framework) durchaus ihre Daseinsberechtigung, gerade für die Zeilgruppe > der Platform. Ich kann mir irgendwie nicht vorstellen, das sich eine > Templateumsetzung genau so einfach handhabt. Kann mich aber natürlich > auch täuschen. Man könnte einiges verbessern. So ist z.B. kein dynamisches Mapping von Pins erforderlich und es ist zur Übersetzungszeit auch kein Geheimnis, welche Pins der Ziehlplattform abzuschaltende Zusatzfunktionen ausführen (PWM). Da die Arduine-Variant aber in einer unübersehbaren Zahl von Libraries verwendet wird, müßte man diese auch anpassen. Schlechtes Base-Library-Design hat eben was virulentes. > Hier haben sich ein paar Leute mal zur Problematik "C++ Interface vs. > Template" ausgelassen. Finde ich ziemlich interessant: > https://stackoverflow.com/questions/16586489/c-interface-vs-template Ja, da geht es bei einer Antwort bzgl. Performance um Intel-PC's, die mit indirekten CALL's weniger Problem wie ein 16MHz 8bitter haben. Das Argument "Compile Time zu lang" ist auf μC Zielsystemen auch keins. Ob der GCC für "plain C" für eins meiner Projekte 100ms braucht, oder mit "Template-Abstraktions-Wahnsinn" 700ms, ist mir egal. Dabei sind das 700% mehr! Und alle anderen sagen klar: Templates! Wobei es möglich ist, ein Interface mit virtuellen Methoden und einer boardspezifischen Implementierung zu haben. Wenn der Compiler die Source der letzteren hat, kann er daraus leicht ein "non-virtuelles" Binary machen.
Oliver J. schrieb: > Torsten R. schrieb: >> Das ist Quatsch (mit Verlaub): > Kein Grund unhöflich werden. Das hast Du Recht: Entschuldige bitte. > Torsten R. schrieb: >> Aber was willst Du mit Laufzeitpolymorphy, wenn >> in Deiner Applikation die Konfiguration statisch ist? > Mir ist leider keine Art bekannt z.b. ein > Proxy-Pattern oder überhaupt Interfaces ohne so etwas *komfortabel* > umsetzen. Dir? Wenn Du tatsächlich in Deiner Applikation sowohl mit einer lokalen, als auch einer remote Gegenstelle kommunizieren must, dann ist das Proxy-Pattern natürlich passend. Dann kannst Du ggf. Entscheidungen erst zu Laufzeit treffen. Wenn Du aber zwei Applikationen hast, und in der einen kommuniziert eine Komponente immer mit einem lokalen Gegenstück und in der anderen kommuniziert diese Komponente tatsächlich immer mit einem remote Gegenstück, dann möchtest Du diese Komponente natürlich gerne in beiden Applikationen verwenden, must aber keine Laufzeitpolymorpie verwenden, weil bereits zur Compile-Zeit klar ist, welches Gegenstück verwendet wird:
1 | class remote |
2 | { |
3 | public: |
4 | void do_it(); |
5 | private: |
6 | /* state */ |
7 | ... |
8 | }; |
9 | |
10 | class local |
11 | { |
12 | public: |
13 | void do_it(); |
14 | }; |
15 | |
16 | template < class DoIt > |
17 | class algorithm : private DoIt |
18 | { |
19 | public: |
20 | void do() |
21 | { |
22 | ... |
23 | this->do_it(); |
24 | ... |
25 | } |
26 | }; |
algorithm erbt von der Implementierung (das ist unüblich), erlaubt aber empty base class optimization im Fall, dass DoIt selbst keine Daten hat (wie im Fall local angedeutet). Wenn klar ist, dass Teile keinen State haben werden, kann man die Funktionen auch static definieren. Das ist nur ein Beispiel, wie man soetwas erreichen kann. Stichworte: Compile Time Polymorphie, Duck Typing, Curiously Recurring Template Pattern, Traits, Mixins. > Torsten R. schrieb: >> Eine "schöne" HAL würde aber auch keine Resourcen verschwenden. Darum >> geht es doch die ganze Zeit in dieser Diskusion: In C++ kannst Du >> Abstraktionen ohne Overhead schaffen! > Das geht natürlich, aber wozu sollte ich das tun, wenn ich die > Anforderung nicht habe? Wenn Du nicht die Anforderungen hast, dass es schön werden soll, dann wird es natürlich nicht schön ;-) mfg Torsten
Torsten R. schrieb: > Wenn Du tatsächlich in Deiner Applikation sowohl mit einer lokalen, als > auch einer remote Gegenstelle kommunizieren must, dann ist das > Proxy-Pattern natürlich passend. Dann kannst Du ggf. Entscheidungen erst > zu Laufzeit treffen. Bei mir muss nix zur Laufzeit entschieden werden. Der Compiler bekommt nur halt nicht alles auf einen Schlag. Wenn ich mal in Platznot komme, dann werde ich sicher nen Unitybuild hernehmen. Dann sollten die vtables ja verschwinden. ;) Ich erläutere einfach mal was ich umgesetzt hab. Konkret geht es bei mir um die I2C-Driver Architektur. Jedes Device bekommt im Konstruktor eine Referenz auf einen I2C-Bus. Der Bus ist komplett abstrakt. Das Pattern Dependency Injektion hab ich deswegen gewählt, weil sich in meinen Augen so ganz einfach Mocks in die TreiberKlassen reingeben lassen und so der UnitTest zum Kinderspiel wird. Abstrakt ist das ganze, weil ich zwei verschiedene Implementierungen von I2C hab (Hardware und Software-Bitbanging) so kann ich je nach Lust und Laune eine der beiden Implementierungen nehmen, je nachdem was gerade benötigt wird und die IC-Treiber brauchen kein Wissen darüber, was sich dahinter befindet. Der Proxy den ich erwähnt hab dient dem Zugriff auf 8 verschiedene I2C-Busse über einen I2C-Multiplexer. Da der Proxy quasi vom Interface her ein I2C-Bus ist, kann ich ihn wieder bequem in die IC-Treiber hineingeben. Torsten R. schrieb: > Wenn Du nicht die Anforderungen hast, dass es schön werden soll, dann > wird es natürlich nicht schön ;-) Gut das Schönheit im Auge des Betrachters liegt. ;) Mir ist natürlich Bewusst, dass das was ich tu nicht wirklich für so kleine Platformen geeignet ist, aber es funktioniert trotzdem in meinen Projekten gut und ich habe wie schon gesagt keine Schmerzen bei der Performance und Platz ist in der Egel auch genug da. Ein so umgesetzter I2C-EEPROM-Programmer auf einem Atmega32U4 schafft über die USB-Serielle von Arduino und dem HardwareI2C-Treiber einen 24C512 in 5 Sekunden komplett zu befüllen und zu verifizieren. Damit bin ich mehr als zufrieden. ;) Wahrscheinlich geht da noch etwas mehr, aber für mich ausreichend.
Meines Erachtens werden bei der ganzen (und vorherigen Diskussionen in diesem Forum) zwei grundsätzliche Dinge nicht beachtet: 1) Die HW ist zu 99% in einer Applikation fest: damit meine ich, dass GPIO-Register feste Adressen haben, die angeschlossenen externen Perioheriekomponenten sind den korrespondierenden Pins fest zugeordnet, es gibt eine definierte Anzahl von internen / externen HW-Komponenten wie UART/I2C/SPI/RTC/USB/... mit definierten Kontrollregistern. Kurzum, an der HW gibt es wenig bis nichts Dynamisches. 2) Die Software-Komponenten aus der Anwendungsdomäne müssen sehr wohl dynamisch sein. Zu 1): hier ist die Frage, wie man statische Sachverhalte modelliert. Ein Weg wäre (wie etwa auch in den Arduino-Bibs) zunächst alles dynamisch zu modellieren. Anschließend muss man sich dann an die statische Natur anpassen. Wie? Da hält die OO-Küche zwar auch einige Pattern und Idiome bereit wie etwa Singleton oder Monostate oder Facade, aber das ist m.E. das Pferd falsch herum aufgezäumt. Weiß ich über die statische Natur, so modelliere ich auch hier statisch, d.h. es gibt dann eben ein MCU::Uart<0> und MCU::Uart<1>, aber die template-Instanziierung von Uart<2> führt zu einem Compilezeitfehler. Auch führt dieses Vorgehen nur zu ganz geringem bzw. gar keinem Code-Bloat, wenn im MCU::Uart-Template nur die tatsächlich von der konkreten Instanziierung abhängigen Code-Anteile drin sind. Oder bei der verstrubbelten Timer-Modularität der AVRs sind dort dann eben nur die spezifischen Anteile in MCU::Timer<0>. Bei den GPIOs ist das natürlich trivial. Das führe ich weiter bis zum einzelnen Pin, also etwa Pin<Port<B>, 3>. zu 2) Hier brauchte ich statische oder begrenzt dynamische Container, d.h. Container, die nur bis zu einer bestimmten Kapazität gefüllt werden können (sofern ich keinen µC mit MMU und dyn. Seitenersetzungsverfahren habe oder gleich ein OS habe). Hier kommt man zu 99% mit den templates analog zu std::array<> bzw. so etwas wie stringbuffer<>, fifo<>, fixedvector<> und stringview<> aus. Auch im klassischen Anwendungsumfeld wie Messen/Steuern/Regeln wird man noch ohne Laufzeitpolymorphie auskommen. Hier steht ja auch oft die Verarbeitungsgeschwindigkeit im Vordergrund. An der Grenze zu komplexeren UIs wird man dann um Laufzeitpolymorphie wohl nicht umhin kommen. Hier sind dann aber die Laufzeitanforderungen moderat, so daß man sich das dann auch leisten kann. Im Übrigen kann man die klassischen Laufzeit-Ansätze wie etwa die Iteration über alle Elemente eines Containers, etwa
1 | for(const auto& item : container) {...} |
analog im statischen haben: das nennt sich klassisch in C++ template-meta-programmierung: hier hat man es mit Meta-Funktionen zu tun (Meta-Funktionen sind selbst wieder templates, denn man "rechnet" ja hier mit Typen und nicht mit Werten): Mit
1 | template<typename... T> |
2 | struct List { |
3 | static void init() { |
4 | (T::init(), ...); |
5 | }
|
6 | };
|
kann man
1 | using led1 = Pin<Port, B>, 1>; |
2 | using led2 = Pin<Port, B>, 4>; |
3 | //...
|
4 | using allLeds = List<led1, led2>; |
5 | allLeds::init(); |
verwenden, und damit kann man etwa mit Faltungsausdrücken iterieren (zur Compilezeit). Was dabei herauskommt ist eine Folge (keine Schleife, kein Funktionsaufruf) von Initialisierungsanweisungen. Hat man sich mit dieser TMP-Technik etwas angefreundet, kann man das obige in der Schreibweise weiter verkürzen, indem man ein paar allgemeine Meta-Funktionen zum Manipulieren von Typ-Listen schreibt:
1 | using leds = Meta::List<led1, led2>; |
2 | using buttons = Meta::List<button1, button2, button3>; |
3 | |
4 | using devices = Meta::concat<leds, buttons>; |
5 | using initializer = Meta::transform<Initialize, devices>; |
6 | |
7 | initializer::init(); |
8 | |
9 | using devices = Meta::apply<function, leds>; |
Die using-Deklarationen sind gewissermaßen Meta-Funktionsaufrufe zur Compilezeit. Noch schöner wird das ganze, durch concepts und constraints (ab z.B. g++-6.1 enthalten). Ein constraints ist in etwa vergleichbar mit einem Interface zur Laufzeit: damit kann man eine implizite Template-Typanforderung explizit machen:
1 | template<typename T> |
2 | concept bool isIsrCallback() { |
3 | return requires(T t) { |
4 | T::isr(); |
5 | T::interrupt_number; |
6 | typename T::interrupt_type; |
7 | };
|
8 | }
|
Auf die Art und Weise kann man dann z.B. die Template-Typ-Parameter beschränken: man verwendet obiges concept als sog. contraint in einer template-definition:
1 | template<typename T> |
2 | requires isIsrCallback<T>() struct Controller {}; |
oder kürzer
1 | template<isIsrCallback T> struct Controller {}; |
Das alles habe ich nur angerissen, doch ich kann eigentlich jedem nur empfehlen, sich mit diesen Dingen, v.a. eben varidischen templates, fold-expressions, constexpr, IIFE, ... auseinander zu setzen. Meines Wissens gibt es dazu bislang kein gute und umfassendes neues(!) Buch (alte zu TMP schon, aber die benutzen meistens noch alte Paradigmen wie SFINAE, ...).
Wilhelm M. schrieb: > Das alles habe ich nur angerissen, doch ich kann eigentlich jedem nur > empfehlen, sich mit diesen Dingen, v.a. eben varidischen templates, > fold-expressions, constexpr, IIFE, ... auseinander zu setzen. Meines > Wissens gibt es dazu bislang kein gute und umfassendes neues(!) Buch > (alte zu TMP schon, aber die benutzen meistens noch alte Paradigmen wie > SFINAE, ...). Vielleicht solltest du ein Buch ala "modern embedded C++" schreiben. ;) Schreibst du selbst deine ganzen Bibliotheken? Ich hab mir nämlich vieles von dir abgeschaut und teils auch selbst nach bestem Wissen eine "template library" ala "Uart<1>" für die STM32L4 Serie gebastelt. Leider stößt man dabei immer wieder auf einige Steinchen. Anstelle von "Uart<1>" verwende ich sowas wie "Uart<DeviceTree:Uart1>", wo etwa Register Definitionen, Interrupts, DMA Kanäle, usw. drin sind. Das funktioniert soweit ganz gut, was ich aber sehr mühsam finde ist, wenn etwa Uart1 2x Features hat, die Uart2 nicht bietet. Aktuell verwende ich eben SFINAE um diverse (statische) Methoden im Template zu deaktivieren, sollte jenes Feature in der entsprechenden Peripherie nicht vorhanden sein. Leider artet das bei komplexen Dingen wie etwa den STM Timern in sehr mühsame Arbeit aus... Da gibts aktuell glaub ich 5-6 verschiedene Timer Implementierungen, die alle ein klein wenig anders sind. Wie gehst du mit sowas um?
Vincent H. schrieb: > Vielleicht solltest du ein Buch ala "modern embedded C++" schreiben. ;) Ich schrieb doch schon: ein Artikel hier im Wiki wäre wirklich sehr sinnvoll. Es nützt einem nicht viel, wenn jemand die ganze Zeit nur sagt: „Ist doch ganz einfach!“ Es ist viel hilfreicher, wenn diejenigen, die wissen, wie es ganz einfach geht, ihr Wissen auch weitergeben - nicht nur in einem Thread, sondern an einer Stelle, wo man es auch später wiederfindet. Das Wiki hier parallel zum Forum ist ein guter Platz dafür.
So ein interessanter Thread! Bitte bitte liebe C++ cracks, teilt etwas von eurem Wissen in einem Wiki Artikel, es wäre zu schade, wenn solche Sachen hier untergingen.
Vincent H. schrieb: > Vielleicht solltest du ein Buch ala "modern embedded C++" schreiben. ;) Ja, so etwas entsteht gerade ... > Schreibst du selbst deine ganzen Bibliotheken? Ja ... (das hat die unterschiedlichsten Gründe) > Leider stößt man dabei immer wieder auf einige Steinchen. Sonst wäre es ja nicht spannend ... > Aktuell verwende ich eben SFINAE um diverse (statische) Methoden im > Template zu deaktivieren, sollte jenes Feature in der entsprechenden > Peripherie nicht vorhanden sein. Leider artet das bei komplexen Dingen > wie etwa den STM Timern in sehr mühsame Arbeit aus... Da gibts aktuell > glaub ich 5-6 verschiedene Timer Implementierungen, die alle ein klein > wenig anders sind. Wie gehst du mit sowas um? Irgendeiner muss die Arbeit ja machen, wenn die HW-Struktur so ... ist. Und in solchen Fällen eine akzeptable Lösung zu finden, ist wirklich eine Kärrnerarbeit. Also ich persönlich finde SFINAE zwar nützlich, aber eigentlich nur bei freien Funktionstemplates sinnvoll, um Überladungen für bestimmten Typen zu aktivieren. Der Klassiker ist hier wohl im µC-Bereich, dass man für die Bits der Kontrollregister scoped enums einführt, und dann gezielt mit einem Trait die Operatoren (etwa |) einschaltet (type safe registers), die man zulassen möchte. Überladungen in Klassentemplates per SFINAE ein/auszuschalten finde ich nicht so "schön". Die Alternative, Template-Spezialisierungen zu verwenden (full-specializations) ist auch unpraktisch, weil ich gerne header-only Bibliotheken möchte (dann muss man sich nicht um das Bauen der Bibliotheken kümmern), und dass dann ggf. zu ODR-Problemen führt. Die m.E. gangbare Variante ist es, über Constraints Klassentemplatespezialisierungen einzuführen und ggf. gemeinsame Anteile als CRTP / mixin zu bauen. Der Vorteil hier ist, dass man ein Concept schreiben kann, dass wie eine vollst. Spezialisierung wirkt, aber zu keinen ODR-Problemen führt, und das es sehr kompakt formuliert werden kann. Andernfalls hat man ja im(!) Template x-fach dieses SFINAE Gewurschtel drin. Dies bedeutet zugegebener Maßen, dass Du einen Compiler brauchst, der Concepts unterstützt (wie etwa gcc ab 6.1).
Jörg W. schrieb: > Vincent H. schrieb: >> Vielleicht solltest du ein Buch ala "modern embedded C++" schreiben. ;) > > Ich schrieb doch schon: ein Artikel hier im Wiki wäre wirklich sehr > sinnvoll. Auch das habe ich gelesen ... ;-) > Es nützt einem nicht viel, wenn jemand die ganze Zeit > nur sagt: „Ist doch ganz einfach!“ Es ist viel hilfreicher, wenn > diejenigen, die wissen, wie es ganz einfach geht, ihr Wissen auch > weitergeben - nicht nur in einem Thread, sondern an einer Stelle, wo > man es auch später wiederfindet. Das Wiki hier parallel zum Forum > ist ein guter Platz dafür. Da ich die Arbeit nicht mehrfach machen möchte, werde ich vermutlich ein eigenes Dokument dort einstellen. Denn ich erzeuge alle techn. Doku mit Asciidoctor inkl. ein paar Tools, Ausgabeformate sind dann html, pdf, ebub, ... Originär hier im Wiki zu schreiben, ist für mich zu umständlich.
:
Bearbeitet durch User
Wilhelm M. schrieb: > Originär hier im Wiki zu schreiben, ist für mich zu umständlich. In einem Wiki nützt es aber nicht viel, wenn du ein PDF nur hinlegst. (Verlinken kannst du es natürlich.) Von asciidoc nach Wiki sollte man nahezu automatisiert übersetzen können. Wenn du das nicht selbst tun willst, wird sich sicher jemand finden, der es macht.
Jörg W. schrieb: > Wilhelm M. schrieb: >> Originär hier im Wiki zu schreiben, ist für mich zu umständlich. > > In einem Wiki nützt es aber nicht viel, wenn du ein PDF nur hinlegst. > (Verlinken kannst du es natürlich.) > > Von asciidoc nach Wiki sollte man nahezu automatisiert übersetzen > können. Mmh, muss mal schauen, wie das dann mit den ganzen Code-Snippets gehen könnte.
Beitrag #5054046 wurde von einem Moderator gelöscht.
Jörg W. schrieb: > Von asciidoc nach Wiki sollte man nahezu automatisiert übersetzen > können. Wenn du das nicht selbst tun willst, wird sich sicher jemand > finden, der es macht. Pandoc kann leider nicht asciidoc direkt lesen aber mit Asciidoctor von asciidoc nach docbook und dann mit pandoc von docbook nach Mediawiki sollte gehen. Unter http://pandoc.org gibt es mehr Infos.
Beitrag #5054785 wurde von einem Moderator gelöscht.
Beitrag #5055979 wurde von einem Moderator gelöscht.
Beitrag #5056167 wurde von einem Moderator gelöscht.
Beitrag #5056189 wurde vom Autor gelöscht.
Beitrag #5056192 wurde von einem Moderator gelöscht.
Beitrag #5056889 wurde von einem Moderator gelöscht.
Beitrag #5057381 wurde von einem Moderator gelöscht.
Beitrag #5057562 wurde von einem Moderator gelöscht.
Beitrag #5057579 wurde von einem Moderator gelöscht.
Beitrag #5058929 wurde von einem Moderator gelöscht.
Beitrag #5059534 wurde von einem Moderator gelöscht.
Beitrag #5059856 wurde von einem Moderator gelöscht.
Beitrag #5060132 wurde von einem Moderator gelöscht.
Beitrag #5060974 wurde von einem Moderator gelöscht.
Beitrag #5061241 wurde von einem Moderator gelöscht.
Beitrag #5061252 wurde von einem Moderator gelöscht.
Beitrag #5062131 wurde von einem Moderator gelöscht.
Beitrag #5062135 wurde von einem Moderator gelöscht.
Beitrag #5065385 wurde von einem Moderator gelöscht.
Beitrag #5066648 wurde von einem Moderator gelöscht.
Beitrag #5067022 wurde von einem Moderator gelöscht.
Beitrag #5067923 wurde von einem Moderator gelöscht.
Beitrag #5069122 wurde von einem Moderator gelöscht.
Beitrag #5069367 wurde von einem Moderator gelöscht.
Beitrag #5070212 wurde von einem Moderator gelöscht.
Beitrag #5070331 wurde von einem Moderator gelöscht.
Beitrag #5071493 wurde von einem Moderator gelöscht.
Beitrag #5071497 wurde von einem Moderator gelöscht.
Beitrag #5072279 wurde von einem Moderator gelöscht.
Beitrag #5073655 wurde von einem Moderator gelöscht.
Beitrag #5073920 wurde von einem Moderator gelöscht.
Beitrag #5073936 wurde von einem Moderator gelöscht.
Beitrag #5076855 wurde von einem Moderator gelöscht.
Beitrag #5077745 wurde von einem Moderator gelöscht.
Beitrag #5078549 wurde von einem Moderator gelöscht.
Beitrag #5079815 wurde von einem Moderator gelöscht.
Beitrag #5082164 wurde von einem Moderator gelöscht.
Beitrag #5085190 wurde von einem Moderator gelöscht.
Beitrag #5085209 wurde von einem Moderator gelöscht.
Wilhelm M. schrieb: > Vincent H. schrieb: >> Aktuell verwende ich eben SFINAE um diverse (statische) Methoden im >> Template zu deaktivieren, sollte jenes Feature in der entsprechenden >> Peripherie nicht vorhanden sein. Leider artet das bei komplexen Dingen >> wie etwa den STM Timern in sehr mühsame Arbeit aus... Da gibts aktuell >> glaub ich 5-6 verschiedene Timer Implementierungen, die alle ein klein >> wenig anders sind. Wie gehst du mit sowas um? > > Irgendeiner muss die Arbeit ja machen, wenn die HW-Struktur so ... ist. > Und in solchen Fällen eine akzeptable Lösung zu finden, ist wirklich > eine Kärrnerarbeit. > > Also ich persönlich finde SFINAE zwar nützlich, aber eigentlich nur bei > freien Funktionstemplates sinnvoll, um Überladungen für bestimmten Typen > zu aktivieren. Der Klassiker ist hier wohl im µC-Bereich, dass man für > die Bits der Kontrollregister scoped enums einführt, und dann gezielt > mit einem Trait die Operatoren (etwa |) einschaltet (type safe > registers), die man zulassen möchte. > > Überladungen in Klassentemplates per SFINAE ein/auszuschalten finde ich > nicht so "schön". Die Alternative, Template-Spezialisierungen zu > verwenden (full-specializations) ist auch unpraktisch, weil ich gerne > header-only Bibliotheken möchte (dann muss man sich nicht um das Bauen > der Bibliotheken kümmern), und dass dann ggf. zu ODR-Problemen führt. > > Die m.E. gangbare Variante ist es, über Constraints > Klassentemplatespezialisierungen einzuführen und ggf. gemeinsame Anteile > als CRTP / mixin zu bauen. Der Vorteil hier ist, dass man ein Concept > schreiben kann, dass wie eine vollst. Spezialisierung wirkt, aber zu > keinen ODR-Problemen führt, und das es sehr kompakt formuliert werden > kann. Andernfalls hat man ja im(!) Template x-fach dieses SFINAE > Gewurschtel drin. > Dies bedeutet zugegebener Maßen, dass Du einen Compiler brauchst, der > Concepts unterstützt (wie etwa gcc ab 6.1). Ein wenig späte Antwort, jedoch bin ich eben draufgekommen, dass Jason Turner (emptycrate.com) offensichtlich vor einem ähnlichen Problem stand. In seinem Chaiscript dürfte jede Menge historischer SFINAE Code stehen, den er in folgender C++ Weekly Episode http://articles.emptycrate.com/2016/07/08/using-c++17s-constexpr-if.html durch constexpr-if ersetzt. Das ist mehr oder weniger ein 1:1 Fix, mit dem man ohne viel Nachdenken die häßlichen Signatures los wird.
Beitrag #5087823 wurde von einem Moderator gelöscht.
Beitrag #5092797 wurde von einem Moderator gelöscht.
Beitrag #5096826 wurde von einem Moderator gelöscht.
Beitrag #5096830 wurde von einem Moderator gelöscht.
Beitrag #5115652 wurde von einem Moderator gelöscht.
Beitrag #5115670 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.