Bin auf eine recht interessante Bibliothek bzw. Framework für die
Bare-Metal-Programmierung mit C++ gestoßen:
http://kvasir.io
Auf der Seite gibt es den Link zum Github-Repo sowie noch ein paar
Youtube-Videos in denen das Framework vorgestellt wird.
Der Ansatz ist ähnlich dem was Wilhelm für AVR hier schonmal vorgestellt
hatte, nutzt also vor allem Sprachmittel aus C++11 wie z.B. constexpr.
"Gefüttert" wird das Framework direkt mit Registerdefinitionen aus den
SVD-Dateien der Hersteller.
Ich persönlich würde mich (derzeit jedenfalls) zwar definitiv in der
C-Ecke verorten aber vielleicht findet ja der ein oder andere seinen
Gefallen daran. Ich finde es jedenfalls einen sehr interessanten Ansatz
und bin gerade dabei mal ein bisschen damit herumzuspielen.
Empfehlen möchte ich auch noch:
https://www.youtube.com/watch?v=n4ie7tPMXOQ
Ich nutze constraints in g++ schon seit geraumer Zeit und möchte diese
feature nicht mehr missen: wesentlich(!) einfacher, leichter zu lesen
und zu schreiben als SFINAE. Und: wir werden es definitiv in C++20
offiziell haben (ggf. mit minimalen Änderungen) ...
Und noch einer:
https://www.youtube.com/watch?v=PFdWqa68LmA
Wobei man beachten sollte, dass die SFINAE Technik, die er hier
anwendet, eigentlich schon wieder veraltet ist -> s.a. concepts.
Trotzdem ist der Vortrag grundsätzlich interessant.
Jörg W. schrieb:> Vincent H. schrieb:>> der ASM/C Fraktion>> Es geht halt nichts über ein gut gepflegtes Vorurteil – oder was soll> diese Bezeichnung sonst sein?
Bitte keine persönlichen Abwertungen in diesem Thread: weder in die eine
noch in die andere Richtung. Dafür gibt es schon genug andere ...
Der Admin mag gerne den letzten Beitrag ohne einen Link löschen.
Jörg W. schrieb:> Raoul D. schrieb:>> Dafür gibt es schon genug andere>> Sehe ich auch so, daher meine Kritik an Vincents unsinnigem Vorurteil.
Wer diese etwas augenzwinkernde Bemerkung als negatives Vorurteil
wertet, fühlt sich wohl selbst ertappt. Also bitte Herr Moderator:
löschen (inkl. dieses Posts)
Wilhelm M. schrieb:> augenzwinkernde Bemerkung
Augenzwinkernd? Sorry, ich sehe da kein Augenzwinkern, sondern
höchstens Evangelismus rausgucken aus so einer Bemerkung. Das ist
doch wie ein Mercedes-Fahrer, der LKW- und Fahrradfahrer in gleichem
Atemzug nennt, weil sie nicht in sein Weltbild passen, zumal sie
suggeriert, dass jemand nicht sowohl Fahrrad, LKW als auch Mercedes
fahren könnte.
> fühlt sich wohl selbst ertappt
Inwiefern?
Ob ich C++ mag, nicht mag, benutze oder nicht benutze hat damit herzlich
wenig zu tun. (Wenn du hin und wieder mehr Beiträge von mir lesen
würdest, wüsstest du außerdem die Antwort darauf. ;-)
Christopher J. schrieb:> Bin auf eine recht interessante Bibliothek bzw. Framework für die> Bare-Metal-Programmierung mit C++ gestoßen:> http://kvasir.io
Wenn man sich die Beispiele in dieser Lib ansieht kann man den Eindruck
kriegen hier mischen die Monitorhersteller mit. Jedenfalls braucht man
für diesen Programmiersteil wohl einen 2m 8K Minitor um ein wenig Code
auf den Schirm zusammenhängend darzustellen...
Mag sein, dass C++ mit den ganzen neuen Erwiterungen eine tolle Sprache
ist, aber verständlicher ist der Code auch nicht als Spagettiecode in C
von vor 20 Jahren. Ich programmiere auch in C++ vermisse aber nichts was
in C++11 oder C++17 hinzu gekommen ist.
Mal was Generelles, die YT-Dokus sind eine Unart. Wir haben
Schriftlichkeit erfunden, und das zu lesen ginge weitaus schneller, als
einem sprechenden Kopf zuhören zu müssen. Wenn es dem sprechenden Kopf
aber zu unwichtig war, es hinzuschreiben, sondern es primär um seine
Selbstvermarktung ging, ist das für den Zuschauer auch verzichtbar.
Davon ab sind noch mehr, noch viel mehr und NOCH VIEL MEHR supertolle
C++-Features generell absolut kein Überzeugungsmittel (im Gegenteil) für
diejenigen, der C++ vor allem wegen des außer Kontrolle geratenen
Sprachumfanges und den sich daraus ergebenden Folgen ablehnt. Daran
ändern auch überflüssige Videodokus nichts.
temp schrieb:> Ich programmiere auch in C++ vermisse aber nichts was> in C++11 oder C++17 hinzu gekommen ist.
Schau dir mal range-based-for, auto und constexpr an. Das sind sehr sehr
praktische Änderungen.
Nop schrieb:> Mal was Generelles, die YT-Dokus sind eine Unart. Wir haben> Schriftlichkeit erfunden, und das zu lesen ginge weitaus schneller, als> einem sprechenden Kopf zuhören zu müssen. Wenn es dem sprechenden Kopf> aber zu unwichtig war, es hinzuschreiben, sondern es primär um seine> Selbstvermarktung ging, ist das für den Zuschauer auch verzichtbar.>> Davon ab sind noch mehr, noch viel mehr und NOCH VIEL MEHR supertolle> C++-Features generell absolut kein Überzeugungsmittel (im Gegenteil) für> diejenigen, der C++ vor allem wegen des außer Kontrolle geratenen> Sprachumfanges und den sich daraus ergebenden Folgen ablehnt. Daran> ändern auch überflüssige Videodokus nichts.
Bin nicht sicher ob jemand der "Dokus" nicht von einer Konferenz
unterscheiden kann überhaupt der "Schriftlichkeit" mächtig ist?
Aber ich gebs eh schon auf. Statt auf irgendeinen der Talks einzugehn
postet man halt lieber Schwachfug, damit man sich nur ja nicht mit der
Materie beschäftigen muss.
Vincent H. schrieb:> Bin nicht sicher ob jemand der "Dokus" nicht von einer Konferenz> unterscheiden kann überhaupt der "Schriftlichkeit" mächtig ist?
Wenn allerdings das erste, was auf einer Webseite zu sehen ist, ein
paar Konferenzvideos sind, eine Doku weit und breit nicht zu erkennen
ist, dann macht das schon stutzig.
Ich würde eine Webseite zum Thema jedenfalls so aufbauen, dass die
Leute die Doku finden (bzw. ich würde nicht nur, sondern ich habe es
in den Projekten, die ich betreue, auch so getan).
Gerade nochmal in deren Git-Repo nachgesehen: Tutorial "coming soon",
doc/ Verzeichnis besteht derzeit aus einigen Zeilen "lorem ipsum".
Leute, was soll das?
Ich hatte diesen Thread eröffnet, um Lesern, die offen für neue Ideen
sind, eine Sammlung von Informationsquellen zu bieten, damit diese sich
nicht alles lebst ergooglen müssen. Die Intention war doch klar, oder?
Und wer einen Aspekt diskutieren möchte, soll bitte dafür einen neuen
Thread eröffnen, damit die Ursprungsquellen hier in der Flut von
Beiträgen nicht untergehen.
Leider passiert hier aber gerade das, was leider in diesem Forum zu oft
passiert: ohne etwas zum Thema beizutragen verteidigen einige mit
offenem Messer ihre eigene Scholle, wobei weder der gute Wille zu
erkennen ist, ggf. über die Fehler anderer hinweg zu sehen noch sich
tatsächlich fundiert mit neuen Aspekten auseinander zu setzen oder
anderen einfach mal zuzuhören, ohne gleich mit schwerem Geschütz zu
antworten.
Wer über die Komplexität der Sprache C++ diskutieren möchte, kann das
gerne ja in einem anderen Thread machen. Aber nicht hier. Wer neue
Features grundsätzlich nicht ansehen und das gerne für alle begründen
möchte, kann das auch in einem anderen Thread machen. Aber nicht hier.
Dieser Thread soll "Futter für die Diskussion" liefern, soll aber nicht
Ort der Diskussion selbst sein. Und wer gleich bei einer flapsigen
Bemerkung hoch geht wie ein HB-Männchen, hat sich in meinen Augen selbst
disqualifiziert.
Wilhelm M. schrieb:> Ich hatte diesen Thread eröffnet, um Lesern, die offen für neue Ideen> sind, eine Sammlung von Informationsquellen zu bieten, damit diese sich> nicht alles lebst ergooglen müssen.
Das ist ja auch völlig OK (und du hast selbst viele Links beigetragen).
Wenn aber jemand einen Link zu einem möglicherweise interessanten
Projekt (wie kvasir.io) postet, dieses Projekt aber bislang außer ein
paar Konferenz-Vorträgen offensichtlich keinerlei Dokumentation hat,
dann sollte man das hier ebenfalls erwähnen dürfen, denn es macht es
potenziellen Nutzern nicht gerade leichter, die Nutzung in Erwägung
zu ziehen.
temp schrieb:> Wenn man sich die Beispiele in dieser Lib ansieht kann man den Eindruck> kriegen hier mischen die Monitorhersteller mit. Jedenfalls braucht man> für diesen Programmiersteil wohl einen 2m 8K Minitor um ein wenig Code> auf den Schirm zusammenhängend darzustellen...> Mag sein, dass C++ mit den ganzen neuen Erwiterungen eine tolle Sprache> ist, aber verständlicher ist der Code auch nicht als Spagettiecode in C> von vor 20 Jahren. Ich programmiere auch in C++ vermisse aber nichts was> in C++11 oder C++17 hinzu gekommen ist.
Gerade die Übersichtlichkeit und Größe des Code wurde durch die neueren
C++-Versionen erheblich verbessert:
Wilhelm M. schrieb:> Wer über die Komplexität der Sprache C++ diskutieren möchte, k
Die Diskussionen sind dort die gleichen - Auseinandersetzungen zwischen
Ideologen. Hier ist ja schon gemütlicher. Die Platformen sind ja auch
kleiner. Vielleicht sind Microcontrollerentwickler auch irgendwie
praktischer, als die Unix-BSD-CPP-Franktion, mit der Ich sonst so zu tun
habe :D
Rolf M. schrieb:> for (const auto& elem : mylist)> {> std::cout << elem << '\n';> }
Ja, das ist besser. Hier gleich noch die Frage, ich brauch neben den
Element noch den 'Index'. In Python loest man das mit enumerate. Was ist
da der moderne C++ Weg? (Man koennt natuerlich ausserhalb der Schleife
eine Variable deklarieren, null setzen und in der Schleife hochzaehlen,
waere das die präferierte Lösung?)
Dumdi D. schrieb:> Rolf M. schrieb:>> for (const auto& elem : mylist)>> {>> std::cout << elem << '\n';>> }>> Ja, das ist besser. Hier gleich noch die Frage, ich brauch neben den> Element noch den 'Index'. In Python loest man das mit enumerate. Was ist> da der moderne C++ Weg? (Man koennt natuerlich ausserhalb der Schleife> eine Variable deklarieren, null setzen und in der Schleife hochzaehlen,> waere das die präferierte Lösung?)
Könntet Ihr bitte die Diskussion zu einem Detailthema in einen eigenen
Thread packen (s.o. erster Beitrag). Damit man den eigentlichen Inhalt
in diesem Thread nicht aus den Augen verliert.
dumdidum (nicht angemeldet) schrieb:> zdumdidum (nicht angemeldet) schrieb:> Scott Meyers: Youtube-Video "Things that Matter - Scott Meyers |> DConf2017"> Wer nicht den ganzen Talk sehen möchte, ich finde 41:00 bis 43:00> erklärt einige Diskussionen.
Ohne nochmal reingeguckt zu haben (hab das Video vor einigen Wochen
gesehen) worum es in dem Abschnitt genau geht: Es ist erwähnenswert,
dass es sich um DConf und nicht um CppCon handelt.
Guideline Support Library
https://github.com/Microsoft/GSL
Ich mag gsl::not_null.
dumdidum (nicht angemeldet) schrieb:> Youtube-Video "Things that Matter - Scott Meyers DConf2017"
"Why is the C++ community having so much trouble?"
...
"Frankly, the standardization committee doesn't really care".
Und das von Scott Meyers! :-)
Type Punning wird ja hier im Forum auch oft diskutiert, dabei werden nur
allzu oft die Unterschiede zwischen C und C++ ausser Acht gelassen (s.a.
unions):
https://www.youtube.com/watch?v=sCjZuvtJd-k
Folgender Talk von Vinnie Falco zeigt wunderbar wie mächtig gutes Design
in modernem C++ sein kann. Das ist insofern erfrischend, weil sich ein
Großteil der Talks halt doch meist auf spezifische und sehr theoretische
Themen bezieht und weniger auf "Problem X -> Lösung Y".
https://www.youtube.com/watch?v=WsUnnYEKPnI
Carl D. schrieb:> More:> http://sbrc2010.inf.ufrgs.br/anais/data/pdf/wtr/st03_01_wtr.pdf>> Dan Saks, CppCon2016: "if you argue, you loose!"> -> keiner der's nicht schon weiß, wird es glauben wollen.
...wobei das Englische "to argue" nicht im Sinne von "argumentieren"
oder "diskutieren" gemeint ist, sondern vielmehr "streiten" meint. Das
ist ein kleiner, aber feiner Unterschied, der häufig zu
Mißverständnissen führt.
Sheeva P. schrieb:> Carl D. schrieb:>> More:>> http://sbrc2010.inf.ufrgs.br/anais/data/pdf/wtr/st03_01_wtr.pdf>>>> Dan Saks, CppCon2016: "if you argue, you loose!">> -> keiner der's nicht schon weiß, wird es glauben wollen.>> ...wobei das Englische "to argue" nicht im Sinne von "argumentieren"> oder "diskutieren" gemeint ist, sondern vielmehr "streiten" meint. Das> ist ein kleiner, aber feiner Unterschied, der häufig zu> Mißverständnissen führt.
Naja, hier ist jeder Versuch einer sachlichen Diskussion in der ein
großes C und zwei Plusszeichen vorkommen, spätesten nach Auftauchen der
"x-beliebig"-Hasser, ein Streit.
Carl D. schrieb:>>> Dan Saks, CppCon2016: "if you argue, you loose!">>> -> keiner der's nicht schon weiß, wird es glauben wollen.>>>> ...wobei das Englische "to argue" nicht im Sinne von "argumentieren">> oder "diskutieren" gemeint ist, sondern vielmehr "streiten" meint. Das>> ist ein kleiner, aber feiner Unterschied, der häufig zu>> Mißverständnissen führt.>> Naja, hier ist jeder Versuch einer sachlichen Diskussion in der ein> großes C und zwei Plusszeichen vorkommen, spätesten nach Auftauchen der> "x-beliebig"-Hasser, ein Streit.
Darauf hat sich Dan bei seiner Aussage aber nicht bezogen, würde ich
vermuten.
Alfred Bratterud
“Delegate this! Designing with delegates in modern C++
https://www.youtube.com/watch?v=QMb4RRFrY-o&index=62&list=PLHTh1InhhwT6bwIpRk0ZbCA0N2p1taxd6
Recht langweiliger Talk über eine sehr nette Klasse. Die im Talk
angesprochene Implementierung findet man im IncludeOS Repo hier:
https://github.com/hioa-cs/IncludeOS/blob/master/api/util/delegate.hpp
Im Grunde verhält sich delegate wie std::function ohne jedoch jemals
Speicher anzufordern. Damit erspart man sich unschöne Überraschungen
wenn man zum Beispiel größere Lambda Objekte in einem function Objekt
ablegen will, die größer sind als der von vornherein reservierte
Speicherplatz.
1
std::array<size_t,3>a1{1,2,3};
2
3
autobig_lambda=[=]()->int
4
{
5
trace_printf("big_lambda: ");
6
returna1[0]+a1[1]+a1[2];
7
};
8
9
// allocates memory (@GCC 7.2 for a cortex M4 platform)
10
std::function<int()>stdf_big_lambda{big_lambda};
Delegate besitzt war auch eine vorab definierte Größe, die ist aber ein
Template Parameter und lässt sich somit justieren. Passt das gewünschte
Objekt nicht hinein, gibts gleich einen Compilezeit Fehler.
Ebenfalls erwähnenswert ist, dass delegate 3x verschiedene
Konfigurationen besitzt. Dies ist am 2. Template Parameter ersichtlich.
Je nach benötigtem Verhalten lässt sich delegate als
- spec::pure (reiner function pointer)
- spec::inplace_triv (function object mit definierter Größe)
- spec::inplace (function object mit definierter Größe, kopierbar,
Destruktor Unterstützung)
anlegen.
Nach meinen Benchmarks (GCC 7.2, -O2, Cortex M4) ist delegate für freie
Funktionen etwa 3.5x, für Lambdas 1.75x schneller.
/edit
Die Default Größe von Delegate ist mit "sizeof(size_t) * 4" für die in
diesem Forum am häufigsten verwendeten Platformen natürlich etwas groß
gewählt... also aufpassen hier.
Jörg W. schrieb:> Wilhelm M. schrieb:>> Ich hatte diesen Thread eröffnet, um Lesern, die offen für neue Ideen>> sind, eine Sammlung von Informationsquellen zu bieten, damit diese sich>> nicht alles lebst ergooglen müssen.>> Das ist ja auch völlig OK (und du hast selbst viele Links beigetragen).>> Wenn aber jemand einen Link zu einem möglicherweise interessanten> Projekt (wie kvasir.io) postet, dieses Projekt aber bislang außer ein> paar Konferenz-Vorträgen offensichtlich keinerlei Dokumentation hat,> dann sollte man das hier ebenfalls erwähnen dürfen, denn es macht es> potenziellen Nutzern nicht gerade leichter, die Nutzung in Erwägung> zu ziehen.
Die "Dokumentation" zu Kvasir und mehr findet man auf Odin Holmes blog :
http://odinthenerd.blogspot.de/
Der name KVasir ist etwas unglücklich gewählt weil der schon mehrfach,
auch für C++, in Gebrauch ist.
Und nun noch ein paar Beiträge zur Sache:
Tutorials und Info zu C++ User-Treffen
http://www.wilkening-online.de/index.html
Und wer gerne ausführliche Dokumentation hätte:
Buch "Real-Time C++" ISBN 978-3-642-34687-3
von Christopher Kormanyos ist lesenswert.
Den Code gibt es hier : https://github.com/ckormanyos/real-time-cpp
Hallo zusammen. War schonmal jmd auf der emBO in Bochum
(https://www.embo.io/#about)? Findet im März wieder statt.
Wird unter anderem von Odin Holmes gehostet. Voll interessant, dass der
in Bochum ansässig ist, ist ganz in der Nähe.
Ich bin eigentlich klassischer C embedded Entwickler, habe aber bei
meiner Firma etwas Raum zum evaluieren von "zukünftigen" (bzw sinnvoll
nutzbaren) Technologien, aber noch nicht besonders bewandert was C++
angeht. Lohnt die Konferenz?
Vincent H. schrieb:> std::array<size_t, 3> a1 { 1, 2, 3};>> auto big_lambda = [=] () -> int
Und da sage noch einer Perl wäre die unleserlichste
Programmiersprache...
Das gute an C++ ist, man kann auch programmieren ohne dass der Code so
aussieht.
Das negative an C++ ist, dass sowas erlaubt ist.
Das gute an C ist, dass sowas nicht möglich ist.
Thomas W. schrieb:> Vincent H. schrieb:>> std::array<size_t, 3> a1 { 1, 2, 3};>>>> auto big_lambda = [=] () -> int>> Und da sage noch einer Perl wäre die unleserlichste> Programmiersprache...>> Das gute an C++ ist, man kann auch programmieren ohne dass der Code so> aussieht.>> Das negative an C++ ist, dass sowas erlaubt ist.>> Das gute an C ist, dass sowas nicht möglich ist.
Das schöne an C++ ist, man muß es nicht nutzen, wenn man es nicht lernen
will. Immer wieder schön anzusehen, wie man dann versucht umständlich
mit C zu bauen, was in C++ ganz einfach geht.
Lernunfauler schrieb:> Das schöne an C++ ist, man muß es nicht nutzen,> wenn man es nicht lernen will.
Und das allerschönste ist, dass man dann den Code nicht lesen kann, den
man maintainen muss, weil einer der früheren Autoren es lernen und üben
wollte.
S. R. schrieb:> Und das allerschönste ist, dass man dann den Code nicht lesen kann, den> man maintainen muss, weil einer der früheren Autoren es lernen und üben> wollte.
Das ist ein Feature, nennt sich WOM auf Quelltextebene. Dient vorrangig
der Arbeitsplatzsicherung.
Nop schrieb:> S. R. schrieb:>>> Und das allerschönste ist, dass man dann den Code nicht lesen kann, den>> man maintainen muss, weil einer der früheren Autoren es lernen und üben>> wollte.>> Das ist ein Feature, nennt sich WOM auf Quelltextebene. Dient vorrangig> der Arbeitsplatzsicherung.
Da braucht man kein C++ für. Das kann man in jeder Sprache tun.
Ich bin zugegebenermaßen ein relativ kleines Licht in der Diskussion.
Ich benutze c (auf Mikrocontrollern) mit, selbst geschätzt, leicht
gehobener Erfahrung. C++ war nur akademischer Natur und das vor einer
guten Dekade. Da habe ich also recht wenig Ahnung und quasi null
Erfahrung.
PC programmiere ich eigentlich nur sporadisch und wenn in c und ersten
Python-Versuchen.
Ich bin allerdings lernwillig mit unangenehm wenig freier Zeit und
möchte mich gerne von den c++ Anhängern anfixen lassen!
Welches Buch würdet ihr mir dafür empfehlen?
Stroustrup habe ich. Allerdings 2. Auflage und so wirklich gut
strukturiert finde ich das auch nicht.
kleines Licht schrieb:> Ich bin allerdings lernwillig mit unangenehm wenig freier Zeit und> möchte mich gerne von den c++ Anhängern anfixen lassen!>> Welches Buch würdet ihr mir dafür empfehlen?> Stroustrup habe ich. Allerdings 2. Auflage und so wirklich gut> strukturiert finde ich das auch nicht.https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list
Dies sind m.E. alles gute Bücher, wenngleich ich persönlich den
Stroustrup auch nicht besonders gut finde, der Lippmann gefällt mir
schon besser ...
kleines Licht schrieb:> Welches Buch würdet ihr mir dafür empfehlen?
Irgendeins, was mindestens C++11 behandelt, moderner ist besser.
Insbesondere für Embedded ist da einiges schönes dabei.
Odin Holmes über "Agent based class design"
https://www.youtube.com/watch?v=tNXyNa6kf4k
Den Talk hatte ich bisher noch nicht im Auge weil der Titel sehr nach
0815 Design-Pattern klingt. Was ich da aber nicht wusste ist, dass Odin
Holmes aus der Embedded Szene kommt weshalb ich mir das ganze mal
angesehn hab... Viel kann ich dazu aktuell nocht nicht sagen, außer dass
es nach einer potenziell sinnvollen Methode aussieht um die immer größer
werdende Komplexität moderner µC Peripherie sinnvoll in den Griff zu
bekommen.
Was aber generell recht interessant ist, ist dass Odin selbst im Talk
Kvasir mittlerweile beinhart als "fail" bezeichnet. Auch der letzte
Commit zum Projekt liegt mittlerweile 1 Jahr zurück.
Auch emBO++ hab ich kurz angesurft, was extrem ernüchternd war. Da gibts
ja NULL Info... außer ein paar Slides. Die können sie sich behalten.
Bitte künftig eine Scheibe bei der CppCon abschneiden.
Vincent H. schrieb:> um die immer größer werdende Komplexität moderner µC Peripherie> sinnvoll in den Griff zu bekommen.
Linux ist Dimensionen komplexer, und für das bißchen µC-Peripherie
braucht es neue Ansätze, weil das nicht mehr beherrschbar sei. Ja nee,
ist klar.
Vincent H. schrieb:> Odin Holmes über "Agent based class design"> Youtube-Video "CppCon 2017: Odin Holmes “Agent based class design”">
Kannte ich auch noch nicht!
>> Was aber generell recht interessant ist, ist dass Odin selbst im Talk> Kvasir mittlerweile beinhart als "fail" bezeichnet. Auch der letzte> Commit zum Projekt liegt mittlerweile 1 Jahr zurück.>
Habe mit ihm mal kurz gesprochen. Er bezeichnet Kvasir als
proof-of-concept, das allerdings teilweise durchaus in Produktionscode
landete. Die MPL Lib war aber langsam. Das wurde aber wohl jetzt in
einem weiteren Repo gelöst und soll (hoffentlich) zurück portiert
werden. Angeblich gibts da eine Roadmap Diskussion auf der emBO++.
> Auch emBO++ hab ich kurz angesurft, was extrem ernüchternd war. Da gibts> ja NULL Info... außer ein paar Slides. Die können sie sich behalten.> Bitte künftig eine Scheibe bei der CppCon abschneiden.
Ja, da könnte es etwas mehr geben :/ Ist nicht mehr lange..
Ich habe mich die Woche mal ein wenig mehr mit Concepts beschäftigt und
versteh nun so langsam die Euphorie vom Wilhelm. ;) Interessanterweise
gibts im Netz trotz des mittlerweile stolzen Alters der Concept TS
(2015?) nicht wirklich viel Info dazu, vor allem nicht im direkten
Vergleich mit so Dingen wie constexpr, variadic templates, etc.
Allein schon die exakte (bzw. aktuelle) Syntax zu finden war etwas
mühsam. So steht quasi nirgends im Netz, dass man grundsätzlich zwischen
(ich nenns mal) "Template" und "Function" Concepts unterscheiden muss.
Und auch deren Anwendung nach einer, wenn auch minimalst,
unterschiedlichen Syntax verlangt...
Und was ich mich nach meinen Spielerein auch langsam frage ist: Was wird
wohl in Zukunft als "gutes" Concept Design angesehn?
Von Stroustrup gibts diesbezüglich von letztem Jänner etwa folgenden
Artikel:
http://www.stroustrup.com/good_concepts.pdf
Den hab ich zwar bisher nur sehr grob überflogen, womit ich (nach 5
Minuten grübeln) aber etwa nicht übereinstimme ist folgende Passage
hier:
> First, let me make a common design mistake. It will make it easier to illustrate
good design.
> I recently saw a concept version of an old OO problem:>> template<typename T>> concept bool Drawable = requires(T t) { t.draw(); } ;
Was er damit wohl meint ist, dass Drawable schlichtweg ein Interface
sein sollte und kein Concept. Generell erwähnt der Artikel öfters, dass
Concepts wohl eher für fundamentale Eigenschaften gedacht sind.
Dabei würde das Concept "Drawable" aber meiner Ansicht nach fantastisch
in den embedded Bereich passen, weil man damit quasi statische
Polymorphie als beinahe Drop-In Replacement zu klassischer Polymorphie
erhält.
Ein schnelles Beispiel hier:
https://godbolt.org/g/j7G1q3
Links die Variante via Vererbung, rechts die Concept Variante...
Ist das in euren Augen eine legitime Nutzung?
Vincent H. schrieb:> Ich habe mich die Woche mal ein wenig mehr mit Concepts beschäftigt und> versteh nun so langsam die Euphorie vom Wilhelm. ;)
Das freut mich!
> Interessanterweise> gibts im Netz trotz des mittlerweile stolzen Alters der Concept TS> (2015?) nicht wirklich viel Info dazu, vor allem nicht im direkten> Vergleich mit so Dingen wie constexpr, variadic templates, etc.>> Allein schon die exakte (bzw. aktuelle) Syntax zu finden war etwas> mühsam. So steht quasi nirgends im Netz, dass man grundsätzlich zwischen> (ich nenns mal) "Template" und "Function" Concepts unterscheiden muss.
Im Concepts-TS gibt es die beiden Formen: function-concept und
variable-concept. Es ist wohl anzunehmen, dass die genaue Syntax in
C++20 etwas davon abweichen wird.
> Und was ich mich nach meinen Spielerein auch langsam frage ist: Was wird> wohl in Zukunft als "gutes" Concept Design angesehn?> Von Stroustrup gibts diesbezüglich von letztem Jänner etwa folgenden> Artikel:> http://www.stroustrup.com/good_concepts.pdf
Da würde ich im Moment nicht viel drauf geben ... (s.u.)
> Dabei würde das Concept "Drawable" aber meiner Ansicht nach fantastisch> in den embedded Bereich passen, weil man damit quasi statische> Polymorphie als beinahe Drop-In Replacement zu klassischer Polymorphie> erhält.
Jein. Was aber sehr interessant ist, dass man nun Klassentemplates mit
Hilfe von Constraints "überladen" kann.
> Ist das in euren Augen eine legitime Nutzung?
Absolut: Dein Anwendungsfall geht in die Kategorie wie Stroustrup das
(ursprünglich) sieht, nämlich, die Fehlermeldungen, die durch ggf. nicht
erfüllte implizite Template-Typanforderungen entstehen, zu
klarifizieren. Aber das ist ja nur die halbe Miete ... (oder weniger als
das).
Wilhelm M. schrieb:>> Dabei würde das Concept "Drawable" aber meiner Ansicht nach fantastisch>> in den embedded Bereich passen, weil man damit quasi statische>> Polymorphie als beinahe Drop-In Replacement zu klassischer Polymorphie>> erhält.>> Jein. Was aber sehr interessant ist, dass man nun Klassentemplates mit> Hilfe von Constraints "überladen" kann.
Jein? Findest du nicht dass man mit Hilfe eines Concepts ein komplettes
Interface beschreiben sollte? Wie gesagt gibts leider wirklich wenig
Infos und komplexere Beispiele... ein "EqualityCompareable" is zwar
nett, aber wie du andeutest sicher nicht das Ende der Fahnenstange. :)
Wilhelm M. schrieb:>> Ist das in euren Augen eine legitime Nutzung?>> Absolut: Dein Anwendungsfall geht in die Kategorie wie Stroustrup das> (ursprünglich) sieht, nämlich, die Fehlermeldungen, die durch ggf. nicht> erfüllte implizite Template-Typanforderungen entstehen, zu> klarifizieren. Aber das ist ja nur die halbe Miete ... (oder weniger als> das).
Wie oben bereits erwähnt, ich sehe gerne Beispiele, Anwendungsfälle oder
ähnliches falls du mal Zeit hast!
Vincent H. schrieb:> Wilhelm M. schrieb:>>> Dabei würde das Concept "Drawable" aber meiner Ansicht nach fantastisch>>> in den embedded Bereich passen, weil man damit quasi statische>>> Polymorphie als beinahe Drop-In Replacement zu klassischer Polymorphie>>> erhält.>>>> Jein. Was aber sehr interessant ist, dass man nun Klassentemplates mit>> Hilfe von Constraints "überladen" kann.>> Jein? Findest du nicht dass man mit Hilfe eines Concepts ein komplettes> Interface beschreiben sollte?
Im allgemeinen assoziieren die meisten Leute mit dem Begriff "Interface"
im Kontext der OOP eine "is-a" Vererbungsbeziehung, in C++ also eine
public-inheritance mit kontra/kovariantem Überschreiben der
Elementfunktionen. Analog dazu definiert ein Constraint bestimmte
Requirements (Anforderungen) an einen Template-Typ-Parameter (oder
Template-Template-Parameter). Insofern ein "ja" zu Deiner Aussage oben.
Allerdings sind Constraints wesentlich allgemeiner als ein Interface und
auch wesentlich weniger (eigentlich gar nicht) gekoppelt.
Auch wenn man DIP konsequent einhält liegt dennoch eine vergleichsweise
enge Koppelung zwischen den Subtypen und den Interface-Typen vor bei der
Schnittstellenvererbung (Laufzeitpolymorphie). Zudem bezieht sich die
Schnittstellenvererbung nur auf die Verhaltenseigenschaft (wobei der
Aspekt der Konformanz regelmäßig ungeprüft bleibt, woran natürlich
concepts auch nichts ändern ...).
Requirements in Constraints können zwar auch eine bestimmte
Schnittstelle des Typs sicherstellen. Allerdings sind die mit dem
fraglichen Typ in keiner Weise gekoppelt (man könnte das mit Duck-Typing
vergleichen). Zudem kann nicht nur die Funktionsschnittstelle (oder auch
nur ein Teilaspekt daraus) geprüft werden, sondern jeder Aspekt des
fraglichen Typs: etwa ob der Typ andere Schnittstellen erfüllt, ob der
Typ bestimmte andere Eigenschaften wie geschachtelte Typen oder
Konstanten enthält, oder ob bspw. wiederum andere generische Typen
parametriert mit diesem Typ bestimmte Eigenschaften erfüllen.
Ich denke, dass sind genügend andersartige Aspekte, die ein "nein" bzw.
dann eben zusammen genommen ein "jein" oben rechtfertigen.
> Wie gesagt gibts leider wirklich wenig> Infos und komplexere Beispiele... ein "EqualityCompareable" is zwar> nett, aber wie du andeutest sicher nicht das Ende der Fahnenstange. :)
Ich finde das Beispiel eigentlich gar nicht so schlecht, weil es einfach
ist, die völlige Kopplungslosigkeit deutlich macht, und sinnvoll nicht
anders bisher in der Sprache dargestellt werden konnte.
>> Wilhelm M. schrieb:>>> Ist das in euren Augen eine legitime Nutzung?>>>> Absolut: Dein Anwendungsfall geht in die Kategorie wie Stroustrup das>> (ursprünglich) sieht, nämlich, die Fehlermeldungen, die durch ggf. nicht>> erfüllte implizite Template-Typanforderungen entstehen, zu>> klarifizieren. Aber das ist ja nur die halbe Miete ... (oder weniger als>> das).>> Wie oben bereits erwähnt, ich sehe gerne Beispiele, Anwendungsfälle oder> ähnliches falls du mal Zeit hast!
Vielleicht sollte man da einen eigenen Thread aufmachen?
Wenn ich mal schnell meine Anwendungsfälle so durchgehe, dann fallen mir
etwa die folgenden ein:
1
template<typenameT>
2
conceptboolNamedFlag(){
3
returnrequires(Tf){
4
T::value;
5
{T::value}->bool;
6
};
7
}
8
template<typenameT>
9
conceptboolNamedConstant(){
10
returnrequires(Tc){
11
T::value;
12
{T::value}->typenameT::value_type;
13
};
14
}
Ich bin dazu übergegangen, alle Konstanten in Typen zu packen: also
statt:
Es wird mal wieder Zeit für kräftige Argumente, heute Boost SML:
http://boost-experimental.github.io/sml/index.html
Boost SML ist der geistige Nachfolger von Boost MSM. Während MSM aber
auf Grund seines Overheads quasi nie embedded-tauglich war erzeugt SML
winzigen Code (vor allem im Vergleich zu std::variant). Was aber
wahrlich beeindruckent ist, ist die schlichte Eleganz mit der sich via
Transition Table die komplette State Machine beschreiben lässt ->
1
// from boost::sml examples
2
3
namespace{
4
structe1{};
5
structe2{};
6
structe3{};
7
8
structstates{
9
autooperator()()constnoexcept{
10
usingnamespacesml;
11
constautoidle=state<classidle>;
12
returnmake_transition_table(
13
*idle+event<e1>="s1"_s
14
,"s1"_s+sml::on_entry<_>/[]{std::cout<<"s1 on entry"<<std::endl;}
15
,"s1"_s+sml::on_exit<_>/[]{std::cout<<"s1 on exit"<<std::endl;}
16
,"s1"_s+event<e2>=state<classs2>
17
,state<classs2>+event<e3>=X
18
);
19
}
20
};
21
}
22
23
intmain(){
24
sml::sm<states>sm;
25
sm.process_event(e1{});
26
sm.process_event(e2{});
27
sm.process_event(e3{});
28
assert(sm.is(sml::X));
29
}
Eine Liste mit den unterstützten UML-features findet sich hier:
http://boost-experimental.github.io/sml/benchmarks/index.html
Als besonders praktisch empfand ich die orthogonal regions, die sich
ausgezeichnet nutzen lassen um immer wieder kehrende Operationen
abzudecken. Klassisch etwa "ADC einlesen" vor jedem eigentlichen State
Machine dispatch.
Vincent H. schrieb:> ist die schlichte Eleganz
Super elegant.... und vor allem so leserlich. ;)
Ich finde , dass ist ein Beispiel, kein C++ zu nehmen. Auch wenn es den
Code rein textuell kürzer macht.
900ss D. schrieb:> Vincent H. schrieb:>> ist die schlichte Eleganz>> Super elegant.... und vor allem so leserlich. ;)>> Ich finde , dass ist ein Beispiel, kein C++ zu nehmen. Auch wenn es den> Code rein textuell kürzer macht.
Und was hindert dich daran einen anderen Ansatz zu wählen, der dir mehr
zusagt? In C könntest du es so jedenfalls nicht formulieren...
TriHexagon schrieb:> Und was hindert dich daran einen anderen Ansatz zu wählen, der dir mehr> zusagt?
Nichts, steht irgendwo, dass mich etwas daran hindert? Ist nur meine
bescheidene Meinung zu diesem Beispiel.
> In C könntest du es so jedenfalls nicht formulieren...
Wohl nicht, aber so find ich es halt bescheiden.
900ss D. schrieb:> Wohl nicht, aber so find ich es halt bescheiden.
Zum Toggeln einer LED würd ich das auch nicht einsetzen, aber du
übersiehst die Vorteile bei komplexeren State Machines.
1.) Statt 23 verschiedener Klassen oder einem 500 Zeilen langen
switch-case steht der gesamte Logik-Teil der State Machine in einer
einzigen Tabelle. Ja natürlich könnte man "transition tables" als
Kommentar in den Code schmeißen... das macht halt nur kein Mensch. ;)
2.) Guards und Actions sind durch das Design Prinzip bereits entkoppelt
und da Single-Responsibility-Principle wird strikt eingehalten. Dadurch
sind Guards und Actions ausgezeichnet testbar. Der Nutzer kann gar
keinen eng-gekoppelten Code schreiben.
3.) Boilerplate bei entry/exit/history/orthogonal regions und sonstigen
"advanced" State Machine features entfällt. Denk mal drüber nach wie du
diese features in C einbauen würdest und wie mühsam das teils wär!
900ss D. schrieb:> TriHexagon schrieb:>> Und was hindert dich daran einen anderen Ansatz zu wählen, der dir mehr>> zusagt?>> Nichts, steht irgendwo, dass mich etwas daran hindert?900ss D. schrieb:> Ich finde , dass ist ein Beispiel, kein _C++_ zu nehmen.
Hier kommst du aber zum Schluss, dass C++ nichts für dich ist, wobei der
Ansatz das eigentliche Problem ist, aber nicht C++. Das meinte ich. Da
ist es ganz egal wie der Ansatz selbst zu bewerten ist.
Zum Ansatz selber, ja optisch jetzt nicht so optimal, aber wenn man eine
komplexere Statemachine aufbaut, dann find ichs schon praktisch. Ich hab
erst kürzlich einen Parser mit einer Statemachine in Plain C aufgebaut.
Ganz einfach mit switch cases und je einer Funktion pro Zustand. Problem
an der ganzen Sache ist, dass sich das total aufbläht und noch schlimmer
ziemlich fehleranfällig ist. Aber das hat Vincent schon ziemlich gut
erläutert.
Vincent H. schrieb:> aber du übersiehst die Vorteile bei komplexeren State Machines.
Gedehntes "vielleicht". :)
Aber lesbar ist es nicht sonderlich und das stört mich daran. Ok, auch
in C muss man das erstmal lesbar formulieren.
Vincent H. schrieb:> Zum Toggeln einer LED würd ich das auch nicht einsetzen, aber du> übersiehst die Vorteile bei komplexeren State Machines.
Ich finde dieses Beispiel ebenfalls abschreckend und unlesbar.
Allerdings unter einer Einschränkung: Wenn man generierten Code (aus
einer eingeschränkten Spezialsprache) betrachtet, spielt Lesbarkeit
keine Rolle. Sollte dieses Beispiel wirklich effizienten Maschinencode
erzeugen, dann meinetwegen.
Aber von Hand und für Menschen geschrieber Code sollte als oberstes
Kriterium lesbar (und wartbar) sein, und er sollte zumindest
verständlich sein, bevor man viele Abstraktionen und Transformationen
einführt (sonst ist die wahre Komplexität nicht abschätzbar).
High-Level-mäßig würde ich sagen: Das Programm ist bereits eine
State-Machine. Kein Grund eine in einer anderen auszudrücken.
"State-Transitionen" sind in C(++) etwa ein Semikolon oder ein
Funktionsaufruf. Definiert C++ für solches Zeug nicht extra Koroutinen?
Auf größeren Geräten macht man halt 'nen Thread auf!
Vincent H. schrieb:> Es wird mal wieder Zeit für kräftige Argumente, heute Boost SML:> http://boost-experimental.github.io/sml/index.html
...
> Als besonders praktisch empfand ich die orthogonal regions, die sich> ausgezeichnet nutzen lassen um immer wieder kehrende Operationen> abzudecken. Klassisch etwa "ADC einlesen" vor jedem eigentlichen State> Machine dispatch.>>
1
>// operator()()
2
>returnmake_transition_table(
3
>*"read_adc"_s+"irq"_e/read_adc="read_adc"_s,
4
>*"s0"_s+"e0"_e/action0="s1"_s,
5
>"s1"_s+"e1"_e/action1="s2"_s
6
>// etc.
7
>);
8
>
Bei der Modellierung von Zustandsautomaten bin ich immer etwas hin- und
her gerissen. Auf der einen Seite sind sie ein wunderschönes Werkzeug
zur Modellierung (z.B. Protokollanalyse) und ein schönes theoretisches
Spielfeld. Auf der anderen Seite ist die eigentliche Logik eines
Zustandsautomaten so simpel, dass sich eine irgendwie geartete
Abstraktion schon durch große Vorteile auszeichnen muss, um sie
einzusetzen. Schließlich ist jedes Objekt eines Typs mit mindestens
einem Datenelement ein Zustandsautomat. Die Praxis zeigt aber auch oft,
dass hier eine weitere Abstraktion oft nicht eingesetzt wird / wenig
sinnvoll ist.
Ich finde die o.g. DSEL von Boost für die SM nicht schlecht. Allerdings
finde ich die Wahl der Zustands-/Event-Identifier als String-UDLs nicht
glücklich. Aber das ist natürlich Geschmacksfrage. Zusätzlich habe ich
mir angewöhnt, statische Dinge im Code auch statisch auszudrücken.
Bei mir kommen SM im wesentlichen in den folgenden Kategorien daher:
1) allg. Typen mit Mutatoren (aka setter): hier ist der Typ die SM
selbst.
2) kleine SM in einem Typ: eine Handvoll Zustände als enum und etwas
if/switch ist ausreichend verständlich, wenn man die Zustände/Events und
Funktionen sinnvoll benennt.
3) mittlere SM: die sequentielle Formulierung mit if/switch-Monster
(etwa > 10 Zustände) ist unschön. Ein andere, deklarative Formulierung
wäre schöner.
Meine Lösung dazu ist etwa folgendes:
In dieser Präsentation wird kurz erklärt was es mit der Boost SML Syntax
auf sich hat. Danach finde ich sie eigentlich gar nicht so übel:
https://www.youtube.com/watch?v=c9Xt6Me3mJ4&feature=youtu.be&list=PL_AKIMJc4roVSbTTfHReQTl1dc9ms0lWH&t=4195Wilhelm M. schrieb:> Meine Lösung dazu ist etwa folgendes:using fsm = FSM<Tr<StateA, StateB,> E1>, Tr<StateB, StateC, E2>, Tr<StateC, StateA, E3>>;> using mapper = EventMapper<fsm, RangeEvent<unsigned char, 'A', 'z', E1>,> ValueEvent<unsigned char, ',', E2>>;> ...> mapper::process(c);
Das sieht auch sehr elegant aus. Hättest du dazu vielleicht ein
lauffähiges Beispiel?
Making C Less Dangerous in the Linux kernel
https://www.youtube.com/watch?v=FY9SbqTO5GQ
In den Kommentaren zeigt sich leider der ähnliche Widerstand wie hier im
Forum ala "type safety is retarted." :/
My daily rant
Ich schreibe FSM in Hochsprachen, so mit if/then/while und so. Ist imho
weit besser lesbar. Mir würde sich ja sofort die Frage stellen, was denn
bei dem Beispiel passieren würde, wenn sich Transitionen überlappen.
Jaja, die Bedingungen werden selbstverständlich in der Reihenfolge
geprüft, in der die Transitionen deklariert sind. Exception safety? Klar
- ist völlig transparent. Transaktional in dem Fall? Ähhh... Um solches
Zeug zu verifizieren muss man entweder die Hochsprache beherrschen
oder die Implementierung von DSL Nummer 287361 checken, bevor man sich
überhaupt dem eigentlichen Problem zuwenden kann. Das ist echt Fancy,
oder nicht?
Natürlich, wenn eine Art von Problemstellung einen hinreichend großen
Teil der gesamten Arbeit ausmacht lohnt sich so etwas... - vielleicht.
Es gäbe dann nämlich auch noch zB SCXML! Das ist standartisiert und
notwendig Data-Driven. Heißt grafische Tools und Klicki-Bunti. Also
unsere P.O. fänden das sicher echt toll - alles so schön anschaulich!
"Kann man nicht von hier besser nach da hinten?"
das beispiel ist abschreckend. genauso wie regex eine dsl ist,
könnte man statemachine in eigene dsl packen.
das wäre sprachübergreifend, mächtig und würde das erfinden des rades
erübrigen.
c++ ist leider viel zu vermurkst geworden.
ich hoffe rust community wird mit features zurückhaltender sein.
die aktuellen ansätze (expression statt statement basiert,
deconstruction mit pattern matching) sind der richtige weg.
c++ ahmt mit std::variant genau das nach ...
Daniel -. schrieb:> ich hoffe rust community wird mit features zurückhaltender sein.> die aktuellen ansätze (expression statt statement basiert,> deconstruction mit pattern matching) sind der richtige weg.> c++ ahmt mit std::variant genau das nach ...
Wie soll C++ mit std::variant rust nachahmen, wenn es boost::variant
offiziell seit Jan 2004 gibt und rust erst seit Jul 2010?
Daniel -. schrieb:> c++ ist leider viel zu vermurkst geworden.
Viele Entscheidungen des Standard Committee kann ich auch nicht
nachvollziehen.
In welcher abgedrehten Welt ist "consteval"
(https://en.cppreference.com/w/cpp/language/consteval) sofort einem
Keyword würdig, ein variant darf aber kein Language Feature werden? Das
is einfach absurd. Pattern Matching auf Sprachebene ist in meinen Augen
DAS fehlende C++ Feature.
Daniel -. schrieb:
>> ich hoffe rust community wird mit features zurückhaltender sein.>> die aktuellen ansätze (expression statt statement basiert,>> deconstruction mit pattern matching) sind der richtige weg.>> c++ ahmt mit std::variant genau das nach ...>Wie soll C++ mit std::variant rust nachahmen, wenn es boost::variant>offiziell seit Jan 2004 gibt und rust erst seit Jul 2010?
Das war mir nicht bekannt. Ich bin seit 2004 fast komplett aus C++ raus.
Für meine typischen Skripte spielt es keine Rolle, ob die
Ausführungszeit
50ms oder 1ms beträgt. Ich bin auf Python umgeswitcht. Mit einwenig C#,
F# und Go. An sich leben die Sprachen vom Ausborgen von Features
untereinander. Das Pendant zu std::variant wäre discriminated union aus
F#.
Womit das Thema bei algebraic data types und type modeling landet.
Bezogen auf C++, hier ein Einblick
https://www.youtube.com/watch?v=ojZbFIQSdl8Vincent H. schrieb:> In welcher abgedrehten Welt ist "consteval"> (https://en.cppreference.com/w/cpp/language/consteval) sofort einem> Keyword würdig, ein variant darf aber kein Language Feature werden? Das> is einfach absurd. Pattern Matching auf Sprachebene ist in meinen Augen> DAS fehlende C++ Feature.
Die Schwierigkeit wird vermutlich darin liegen, das Zusammenspiel
mit anderen Konzepten so zu gestalten, dass keine gefährlichen
Doppeldeutigkeiten entstehen.
Ich halte mich bei C++ meistens an "alt bewährtes" (~ C++11).
Ich hatte vor Kurzem mit touchgfx Bibliothek zu tun und bin
von derem C++ Still auch in dieser Hinsicht bestätigt worden.
>>Wie soll C++ mit std::variant rust nachahmen, wenn es boost::variant>>offiziell seit Jan 2004 gibt und rust erst seit Jul 2010?
vielleicht könnte man Rust die Einführung von "move" attributieren,
die C++ ja bekanntlich nun auch hat. Allerdings muss hier der
Programmierer
aufpassen alles richtig zu tun.
Daniel -. schrieb:> vielleicht könnte man Rust die Einführung von "move" attributieren,
Versucht du jetzt zu behaupten, dass C++ move Semantik hat, weil es rust
gibt? Dir ist klar, dass es move seit c++11 gibt und dass man so einen
Standard nicht in ein paar Wochen zusammenschustert?
Daniel -. schrieb:> das beispiel ist abschreckend. genauso wie regex eine dsl ist,> könnte man statemachine in eigene dsl packen.> das wäre sprachübergreifend, mächtig und würde das erfinden des rades> erübrigen.
Mein Punkt war eher: das Beispiel ist eigentlich okay, aber trotzdem
völlig ungeeignet, damit im Team ernsthaft zu arbeiten oder solchen Code
ggf. in andere Hände zu geben. Deswegen ist das mit der Feature-Flut in
C++ auch eine zweischneidige Sache. Ich persönlich habe schon den
Eindruck, dass man von der Sprache nicht mehr unbedingt alles in Tiefe
erfassen kann (oder das nur so stückchenweise wird tun können). Dadurch,
dass es diese Möglichkeiten aber gibt, ist man, wenn man sie braucht,
nicht darauf verwiesen, sich gleich völlig in exotisch-akademische
Gefilde zu begeben, von denen man dann noch viel, viel weniger Ahnung
hat. Wer zückt schon gleich Eiffel, wenn er meint, dass ein Stück seiner
Anwendung es Wert wäre, sie mit constraints zu versehen? Soll man sowas
ernsthaft mit asserts lösen? Merke: Die stehen in der Implementierung!
Ich bin nicht mehr sicher, wo das stand - aber ein übermäßig großer
Prozentsatz von Security-Issues zum Beispiel wird, direkt oder indirekt,
durch ungeprüfte 3rd-Party-Libraries verursacht. Mal nicht geprüft, was
die genau tut, und schon knallts. - "Ist doch völlig intuitiv zu
bedienen."
Siehe zum Beispiel den Robot-Attack https://robotattack.org/. "Einfach
mal 'ne SSL-Lib reingelinkt"
1
So, at some point last year, Hanno and friends decided to ask the Internet another question: do web servers really still have RSA padding oracles, the kind Daniel Bleichenbacher discovered back in 1998? It’s 20 years later! We’ve dealt with that problem by now, right?
2
3
And the result is a Bleichenbloodbath.
4
5
They’re publishing documents signed with Facebook’s private key (not once, but twice, breaking Facebook’s fix for the bug). They’ve killed the RSA on F5 Big-IP boxes. Does anyone still use Radware? I guess they do, because the ROBOT team broke those. Citrix, too. Cisco’s ACE boxes are broken — Cisco won’t fix them, mind you, because they’re out of support now, but, oh shit, hold on, CISCO.COM is vulnerable too! Paypal’s vulnerable! A chunk of the Alexa top million. BouncyCastle breaks. The custom non-OpenSSL libraries like WolfSSL and MatrixSSL break. Erlang is broken. Cavium is broken. Unisys ClearPath MCP is broken! The MCP! It’s bananas.
Vincent H. schrieb:> Youtube-Video "CppCon 2019: Timur Doumler “Type punning in modern C++”"
Tja, in C kann man problemlos type punning mit unions machen, jedenfalls
seit C99. Geht in C++ halt wegen name mangling nicht.
Lustig ist auch, daß das, was er als "C style cast" bezeichnet, in C
ebenfalls UB wäre, zumindest bei seinen Beispielen.
Was übrigens bezüglich aliasing im Standard-C++ nicht vorhanden ist, das
ist "restrict", wie C das seit C99 hat. Kommt natürlich daher, daß man
in C++ immer weniger mit direkt Pointern arbeitet und restrict nie für
Klassen entworfen war.
Nop schrieb:> Vincent H. schrieb:>>> Youtube-Video "CppCon 2019: Timur Doumler “Type punning in modern C++”">> Tja, in C kann man problemlos type punning mit unions machen, jedenfalls> seit C99. Geht in C++ halt wegen name mangling nicht.
Das hat mit name-mangling gar nichts zu tun: wird doch alles in dem
guten Vortrag besprochen und ist auch hier im Forum x-mal diskutiert
worden (und wird es wohl auch in Zukunft werden).
Wilhelm M. schrieb:> Das hat mit name-mangling gar nichts zu tun: wird doch alles in dem> guten Vortrag besprochen
Nein, wird es nicht. Da wird nur gesagt, DASS es in C++ eben UB ist (bei
10:19), aber nicht wieso. Und C++ wird hier mit dem bitcast in C++23 ein
Problem lösen, das man in C schon seit 20 Jahren auch ohne memcpy nicht
mehr hat.
Es wird aber zumindest gesagt, dass z.B. type aliasing in C++ auf den
selben Typ erlaubt sind. Auf unterschiedliche Typen aber eben nicht,
weil dann der Compiler paranoid sein müsste und damit schlecht
optimiert.
Warum aber konkret type punning mit unions bei C++ nicht erlaubt ist
wird aber mMn nicht gesagt und verstehe ich auch noch nicht 100%.
Jan schrieb:> Es wird aber zumindest gesagt, dass z.B. type aliasing in C++ auf den> selben Typ erlaubt sind. Auf unterschiedliche Typen aber eben nicht,> weil dann der Compiler paranoid sein müsste
das erwarte ich von ihm
> und damit schlecht> optimiert.
Nein, je paranoider, desto besser die Optimierung.
> Warum aber konkret type punning mit unions bei C++ nicht erlaubt ist> wird aber mMn nicht gesagt und verstehe ich auch noch nicht 100%.
Wird alles im Vortrag ausführlich behandelt, sogar mit Auszügen des
Standards.
Die Stichworte sind: object-lifetime und strict-aliasing
Wilhelm M. schrieb:> Nein, je paranoider, desto besser die Optimierung.
Ein paranoider Compiler muss davon ausgehen, dass nichts von dem, was er
tut, real oder persistent ist, z.B. der Speicher. Aus der Annahme, dass
alle Variablen jederzeit ihren Inhalt ändern können (Paranoia) folgt
also, dass alle Variablen volatile sein müssen. Keine gute
Optimierungsgrundlage.
Oder du hast eine seltsame Definition von paranoiden Compilern. :-)
Wilhelm M. schrieb:> Wird alles im Vortrag ausführlich behandelt, sogar mit Auszügen des> Standards.
Die Frage ist nicht, ob es im Standard steht (tut es), sondern warum man
das in C++ nicht so gemacht hat wie in C.
Object lifetime wird's ja wohl nicht sein, weil unions in C++ ohnehin
keine eigenen Konstruktoren, Destruktoren usw. enthalten dürfen - woher
sollte der Compiler auch wissen, welchen er bei der Deklaration aufrufen
soll.
Strict aliasing - ja, hat C auch, und trotzdem darf man union type
punning machen. In C++ dagegen nicht. Aber warum? Hat man union type
punning in C++ einfach für unwichtig gehalten und sich daher lieber
zugunsten von Performance entschieden, weil weniger erlaubtes aliasing
ja auch weniger reloads bedeutet?
In dem Fall wäre das Argument wohl, daß man ja seit jher noch memcpy
hat, was der Compiler in dem Fall sowieso wegoptimiert, so daßr union
type punning als Feature nicht zwingend notwendig ist.
Nop schrieb:> weil unions in C++ ohnehin> keine eigenen Konstruktoren, Destruktoren usw. enthalten dürfen
Doch, dürfen sie. Das macht sich z.B. std::variant zunutze. Warum auch
nicht - unions sind dazu da, Speicher zu sparen indem man im selben
Bereich nacheinander unterschiedliche Objekte anlegt, statt sie ständig
"parallel" herumliegen zu haben. Das soll dann natürlich auch mit
Klassen funktionieren, welche Konstruktoren haben usw.
Nop schrieb:> woher> sollte der Compiler auch wissen, welchen er bei der Deklaration aufrufen> soll.
Je nachdem welcher Member im Konstruktor der union selbst initialisiert
wird.
Bei so einem Konstrukt
1
#include<string>
2
#include<iostream>
3
4
usingstd::string;
5
6
unionFoo{
7
Foo():str("foo"){}
8
~Foo(){str.~string();}
9
10
stringstr;
11
floatf;
12
};
13
14
intmain(){
15
Foof;
16
std::cout<<f.f<<std::endl;
17
}
Was soll da rauskommen? Die Ausgabe ist jedes Mal eine andere. Weil das
UB ist, darf der Compiler das Programm komplett verunstalten.
Niklas G. schrieb:> Doch, dürfen sie.
Nee, ich meinte das als union von Klassen, die ihrerseits Konstruktoren
haben. Das geht nicht, d.h. im Wesentlichen kann man unions nur über
PODs legen. Folglich ist die object lifetime hier kein spezieller
Gesichtspunkt gegen type punning.
Nop schrieb:> Nee, ich meinte das als union von Klassen, die ihrerseits Konstruktoren> haben.
Ja, und das geht, wie im Beispiel gezeigt - string hat einen Konstruktor
und Destruktor!
Nop schrieb:> Das geht nicht, d.h. im Wesentlichen kann man unions nur über PODs> legen.
Nein, du kannst beliebige Klassen in eine union legen, wie eben string,
vector, und auch solche mit virtuellen Funktionen. Sehr praktisch um auf
Systemen mit wenig Speicher (Mikrocontroller) das State Pattern zu
implementieren.
Nop schrieb:> Niklas G. schrieb:>>> Doch, dürfen sie.>> Nee, ich meinte das als union von Klassen, die ihrerseits Konstruktoren> haben. Das geht nicht, d.h. im Wesentlichen kann man unions nur über> PODs legen. Folglich ist die object lifetime hier kein spezieller> Gesichtspunkt gegen type punning.
Bist du sicher, dass du von C++ redest?
Nop schrieb:> Niklas G. schrieb:>>> Doch, dürfen sie.>> Nee, ich meinte das als union von Klassen, die ihrerseits Konstruktoren> haben. Das geht nicht, d.h. im Wesentlichen kann man unions nur über> PODs legen. Folglich ist die object lifetime hier kein spezieller> Gesichtspunkt gegen type punning.
Ich glaube, Du weißt nicht sehr viel über C++.
Aber wenn Du so etwas unbedingt in Frage stellen willst, dann mach bitte
einen eigenen Thread dazu auf.
Niklas Gürtler schrieb:> Nein, du kannst beliebige Klassen in eine union legen, wie eben string,> vector, und auch solche mit virtuellen Funktionen.https://en.cppreference.com/w/cpp/language/union sagt mir:
"A union can have member functions (including constructors and
destructors), but not virtual functions."
Und das galt nur bis C++11:
"Unions cannot contain a non-static data member with a non-trivial
special member function (copy constructor, copy-assignment operator, or
destructor)."
OK, dann verstehe ich Wilhelms Argument mit der object lifetime auch.
Die "kleinen" Features sind manchmal die nützlichsten:
https://www.youtube.com/watch?v=Xb6u8BrfHjw
Und mein "Liebling" constinit kommt auch vor (nicht dort erwähnt,
vermeidet aber auch _guards für statics).
Wilhelm M. schrieb:> Und mein "Liebling" constinit kommt auch vor (nicht dort erwähnt,> vermeidet aber auch _guards für statics).
Was sich bisher durch -fno-threadsafe-statics aber auch vermeiden ließ.
Vincent H. schrieb:> Wilhelm M. schrieb:>> Und mein "Liebling" constinit kommt auch vor (nicht dort erwähnt,>> vermeidet aber auch _guards für statics).>> Was sich bisher durch -fno-threadsafe-statics aber auch vermeiden ließ.
Leider nicht komplett: zwar wurden oft die lock/count-calls nicht
generiert, dafür hatte man die _guards trotzdem.
Außerdem wirkt -fno-threadsafe-statics nur auf local-statics und nicht
auf static-members oder globals.
Absolut fantastischer Talk von Matt Godbolt über die Entwicklung eines
Path-Tracers in 3 verschiedenen Paradigmen (OO, FP und data-oriented)
https://youtu.be/HG6c4Kwbv4I
Leider gegen Ende auch etwas traurig da er aufzeigt dass man als
Entwickler in Zeiten von Caches und Branch-Prediction Punkto Performance
weniger Mitspracherecht besitzt als einem vielleicht lieb wär...
Ja, der Vortrag ist super; danke.
Das Ende zeigt in erster Linie nur, dass man in Bezug auf Performance
nicht nur wenig Mitspracherecht hat, sondern dass alle Ansätze sehr
empfindlich auf Kleinigkeiten reagieren können.
Ich sehe zwei wesentliche Punkte als Schlussfolgerung für mich:
- für kleine Mikrocontroller sollte die DoD-Variante (effektiv "C-Code
mit STL") wesentlich effizienter sein als die Alternativen, weil nur die
Hälfte an Instruktionen nötig sind;
- für große Prozessoren ist Lowlevel-Optimierung auf dieser Ebene für
mich irrelevant, da die Performance-Schwankungen zu groß sind - würde
sich nicht lohnen, lesbarer Code ist wichtiger.
Nicht neu, aber immer wieder erwähnenswert (sollten sich auch die C
Leute mal anschauen):
https://www.youtube.com/watch?v=KJW_DLaVXIY
Die entsprechenden Warnungen sind im gcc-trunk schon umgesetzt, was ich
sehr lobenswert finde.
Es wäre nett, wenn es zusätzlich zu den DeineRöhre-Links noch eine kurze
Zusammenfassung des Inhalts gäbe. Nicht jeder wird sich, nur weil jemand
einen Vortrag ganz toll findet, einfach mal so XXX Minuten Videos
angucken wollen, wenn er vorher noch gar nicht weiß, ob ihn das Thema
wirklich sooo brennend interessiert.
Jörg W. schrieb:> Es wäre nett, wenn es zusätzlich zu den DeineRöhre-Links noch eine kurze> Zusammenfassung des Inhalts gäbe. Nicht jeder wird sich, nur weil jemand> einen Vortrag ganz toll findet, einfach mal so XXX Minuten Videos> angucken wollen, wenn er vorher noch gar nicht weiß, ob ihn das Thema> wirklich sooo brennend interessiert.
Wozu? Ein Klick auf den Link und Du hast das Video, und jeder
Vortragende fängt mit einer Agenda an, so wie sich das gehört. Da hast
Du doch alle Infos, zudem auch einen Eindruck vom Vortragenden selbst
inkl. seiner sprachlichen Qualitäten.
Wilhelm M. schrieb:> Nicht neu, aber immer wieder erwähnenswert (sollten sich auch die C> Leute mal anschauen):>> https://www.youtube.com/watch?v=KJW_DLaVXIY>> Die entsprechenden Warnungen sind im gcc-trunk schon umgesetzt, was ich> sehr lobenswert finde.
Obwohl er eigentlich recht hat, hätte ich mir etwas mehr "dafür braucht
man es wirklich" gewünscht. Und weniger "keine Ahnung warum, aber es
scheint zu manchmal helfen".
Wilhelm M. schrieb:> Jörg W. schrieb:>> Es wäre nett, wenn es zusätzlich zu den DeineRöhre-Links noch eine kurze>> Zusammenfassung des Inhalts gäbe. Nicht jeder wird sich, nur weil jemand>> einen Vortrag ganz toll findet, einfach mal so XXX Minuten Videos>> angucken wollen, wenn er vorher noch gar nicht weiß, ob ihn das Thema>> wirklich sooo brennend interessiert.>> Wozu? Ein Klick auf den Link und Du hast das Video, und jeder> Vortragende fängt mit einer Agenda an, so wie sich das gehört. Da hast> Du doch alle Infos, zudem auch einen Eindruck vom Vortragenden selbst> inkl. seiner sprachlichen Qualitäten.
Zusätzlich gibt es auf youtube für das Video einen kurzen Text des
Vortragenden.
Damit Wilhelm nicht die Links sämtlicher 920 CppCon-Videos einzeln
posten muss:
Hier sind sie alle auf einmal:
https://www.youtube.com/user/CppCon/videos
Da kann sich jeder genau das aussuchen, was ihn persönlich am meisten
interessiert.
PS: Der wahre C++-Freak klickt jetzt einfach auf "PLAY ALL" und lehnt
sich für die nächsten fünfeinhalb Wochen entspannt in seinem Sessel
zurück ;-)
Wilhelm M. schrieb:> Youtube-Video "CppCon 2019: JF Bastien “Deprecating volatile”"
Das mit den Bitfields und Register: So verwendet man Bitfields nicht,
weil der Standard nicht definiert, wie die Bits im Bitfield angeordnet
sind.
Den "Verbesserungsvorschlag" an sich finde ich z.T. sinnfrei, weil man
bei "x=x+1" ebensowenig wie bei "x+=1" oder "++x" weiß, ob das atomar
ist oder nicht, weil das eh vom Befehlssatz der CPU und außerdem dem
Datentyp von x abhängt.
Es fügt lediglich eine neue Regel hinzu, daß bei volatile-Variablen der
übliche syntaktische Zucker auf einmal nicht mehr funktioniert. IMO ein
nerviges Antifeature.
Nop schrieb:> Wilhelm M. schrieb:>>> Youtube-Video "CppCon 2019: JF Bastien “Deprecating volatile”">> Das mit den Bitfields und Register: So verwendet man Bitfields nicht,> weil der Standard nicht definiert, wie die Bits im Bitfield angeordnet> sind.
Darüber spricht er auch nicht. Er prangert nur an, dass für diesen Fall
die Bedeutung von volatile nicht klar definiert ist, wie an vielen
anderen Stellen auch.
> Den "Verbesserungsvorschlag" an sich finde ich z.T. sinnfrei, weil man> bei "x=x+1" ebensowenig wie bei "x+=1" oder "++x" weiß, ob das atomar> ist oder nicht, weil das eh vom Befehlssatz der CPU und außerdem dem> Datentyp von x abhängt.
volatile und atomic hat auch nichts miteinander zu tun. Bei einem
volatile x = x + 1; ist es klar, dass explizite load/store (und damit
nicht atomare) Instruktionen generiert werden müssen. Bei ++x; erscheint
das nicht so klar. Es geht bei dieser speziellen Ausprägung "nur" um die
Intentionalität des Codes. Deswegen wurde auch ein ganz anderes API wie
volatile_store() / volatile_load() vorgeschlagen, um die
nicht-notwendige Atomarizität deutlich zu machen.
> Es fügt lediglich eine neue Regel hinzu, daß bei volatile-Variablen der> übliche syntaktische Zucker auf einmal nicht mehr funktioniert. IMO ein> nerviges Antifeature.
Für mich das genaue Gegenteil.
Ich glaube der hier
https://www.youtube.com/watch?v=KAWA1DuvCnQ
von Scott wurde noch nicht hier gelistet.
Ein amüsanter, augenzwinkernder Vortrag, der wohl auch über so ziemlich
jede Sprache und Ihre Bibliothek gehalten werden könnte. Trotzdem: er
enthält eine sehr wichtige Botschaft.
Vincent H. schrieb:> Ich mag Talks die für ein Problem verschiedene Lösungen präsentieren:> Youtube-Video "[MUC++] Klaus Iglberger - Embrace No Paradigm> Programming!"
Generell stimme ich dir zu, verschiedene Lösungen sind super. Er gibt
einen ganz guten Überblick, über die verschiedenen Möglichkeiten. Aber
die Bewertungskriterien sind für mich nicht wirklich nachvolliehbar.
Ein paar Dinge die mir beim gucken sofort aufgefallen sind (bitte nicht
in diesem Thread die Punkte selbst diskutieren):
Warum z.B. bekommt die std::function Variante eine 7 bei "Seperation of
Concerns"? Jede shape muss jede Operation kennen und zusätzlich noch die
DrawStrategy. Was ist daran besser als bei der enum oder OO Variante?
Und warum hat std::function die zweit beste Simplicity-Wertung? Wenn ich
z.b. mit OpenGl auf den Bildschirm und zusätzlich als pdf zeichnen will,
müssen alle shapes kopiert werden, damit sie ne andere Strategy bekommen
können. Warum bekommt die variant Version so ne schlechte "Addition of
Shapes" Bewertung? Ja, man muss alle Visitor modifizieren, aber der
Compiler sagt einem, wo die sind, wenn man welche vergisst.
Ich sehe keinen Unterschied, ob ich für PCs oder MCUs entwickle. Es geht
einzig um die Funktion, Struktur und Umfang des Programmes. Und wenn ich
ein OS ansteuern möchte, braucht es MT-Unterstützung, die man in C
einfach nicht hat.
Cppcon ist vorbei und das erste Video ist auf youtube
(https://www.youtube.com/channel/UCMlGfpWw-RUdWX_JbLCukXg) aufgetaucht.
Mal schauen was dieses Jahr an interessanten Beiträgen dabei ist. Wenn
es wie in den letzten Jahren läuft, dauert es einige Wochen, bis alle
Beiträge online sind. Das Programm ist unter
https://cppcon.org/program2020/ zu finden.
Assembler: Wird nur noch benutzt, wenn es wirklich absolut nicht anders
geht, sprich zur Optimierung. Ganze Projekte in Assembler habe ich nur
zu Anfang gemacht, fand das damals cool - würde ich aber heute
konsequenterweise grundsätzlich ablehnen.
C: Wird nur noch angewendet, wenn C++ nicht zur Verfügung steht.
C++: Ist auf Mikrocontrollern für mich inzwischen Standard. Da die
meisten auf ARM basieren, ist in der Regel C++ möglich. Auch AVR lassen
sich mit C++ programmieren.
Also auf C oder Assembler weiche ich selbst bei kleinen Mikrocontrollern
nur noch im Notfall aus. Assembler nur noch zur Optimierung einzelner
Stellen. Und da andere Sprachen eh Mangelware sind, ist das das Mittel
der Wahl.
Wilhelm M. schrieb:> Oh ha, dann bist Du wohl noch nicht lang in diesem Forum ;-)
Angemeldet seit 24.10.2019 09:12 - bin jedoch in Wirklichkeit schon seit
über 10 Jahren dabei. Ich Autist verstehe deine Anmerkung dennoch nicht
😁 ... ja der Thread wurde ausm Grab geholt.
Ben S. schrieb:> Ich Autist verstehe deine Anmerkung dennoch nicht
In diesem Forum wird ja C++ für µC regelmäßig verteufelt. Ich habe da
seit Jahren eine andere Sichtweise, und es gab/gibt immer noch
entsprechende Kommentare. Doch nun scheint die Erkenntnis auch bei
solchen Hochglanz-Seminaren angekommen zu sein. Wobei in der ernsthaften
Entwicklerwelt sich das Thema "Modernes C++ auf µC" doch schon mehr
durchgesetzt hat.
Ben S. schrieb:> Wilhelm M. schrieb:>> Oh ha, dann bist Du wohl noch nicht lang in diesem Forum ;-)>> Angemeldet seit 24.10.2019 09:12 - bin jedoch in Wirklichkeit schon seit> über 10 Jahren dabei. Ich Autist verstehe deine Anmerkung dennoch nicht
Es ging um die Verteilung der Vorlieben. Viele mögen C++ nicht, weil
angeblich viel zu fett für arme kleine Rechner. Manche hassen sogar
alles, was mit C anfängt.
> 😁 ... ja der Thread wurde ausm Grab geholt.
Das ist eher ein schlafender Thread, der an so Dinge wie "es ist wieder
CppCon-Zeit" erinnern soll. Traffic hat der nur, wenn es keine
Alternativen gibt. Aktuell läuft "weshalb Linux so blöd ist" auf einem
Parallel-Thread, da bleibt es hier ruhig.
Wilhelm M. schrieb:> Doch nun scheint die Erkenntnis auch bei solchen Hochglanz-Seminaren> angekommen zu sein.
Naja, c++ für embedded (auch Cortex m3) Kurse gibt's aber schon länger,
zb von microconsult oder beningo.
Tatsächlich überlege ich aber gerade, welche Fortbildung nächstes Jahr
sinnvoller ist. Wollen über den Tellerrand gucken. C++ oder Rust.
Speziell Richtung testen von kleinen eingebetteten Systemen. Fundiertes
C Wissen ist vorhanden, C++ sehr rudimentär, wobei ich die Features der
neueren Versionen und dem was hier so vorgestellt wird auch sehr
interessant finde.
Meinungen?
Wilhelm M. schrieb:> der Titel sagt es schon: es geht um das (alte) Thema: C vs C++ für> eingebettete Systeme / MCUs.
Du hast das Thema verfehlt, weil Deine Links (habe nicht alle probiert)
entweder schon gestorben sind (z.B. erster Link) oder aber zu 99% C++
behandeln.
Schade, weil die Idee mit der Linksammlung gut war.
Benenne das Thema in Embedded Programmierung mit C++ um, dann stimmt es
:-)
Robert K. schrieb:> Du hast das Thema verfehlt, weil Deine Links (habe nicht alle probiert)> entweder schon gestorben sind (z.B. erster Link) oder aber zu 99% C++> behandeln.
Tja, Du kommst eben mindestens 4 Jahre zu spät ...
Vincent H. schrieb:> Ben Deane über 'deducing this'> https://youtu.be/jXf--bazhJw>> In meinen Augen das wohl sinnvollste C++23 (?) Feature für die Embedded> Entwicklung.
Von den Features, die bis jetzt sicher sind. Und ich würde das Embedded
aus der Aussage streichen ;-)
Wilhelm M. schrieb:> Und das leidige Thema der views (und des non-propagating-const) mal> schön dargestellt:
Na danke. Jetzt habe ich das Gefühl, dass die Standardisierungsgruppe
komplett den Verstand verloren hat…
Rolf M. schrieb:> Wilhelm M. schrieb:>> Und das leidige Thema der views (und des non-propagating-const) mal>> schön dargestellt:>> Na danke. Jetzt habe ich das Gefühl, dass die Standardisierungsgruppe> komplett den Verstand verloren hat…
Das gab es in der Vergangenheit auch schon mehrfach. man denke an
std::auto_ptr<> oder std::thread<>.
Naja, auto_ptr war dann doch von den Auswirkungen her deutlich
begrenzter als die Views. Ich bin aktuell noch bei C++17, aber nach dem
Vortrag werde ich die Views wahrscheinlich nicht einsetzen, weil sie
einfach kaputt sind. Das sind mir zu viele Stolpersteine.
Leider scheint es auf Josuttis' github-Seite seine "Belleviews" nicht
mehr zu geben. Weißt du, was damit passiert ist?
Rolf M. schrieb:> Leider scheint es auf Josuttis' github-Seite seine "Belleviews" nicht> mehr zu geben. Weißt du, was damit passiert ist?
Lizenzverletzung, daher musste das Repo erstmal gelöscht werden.
Wilhelm M. schrieb:> Rolf M. schrieb:>> Wilhelm M. schrieb:>>> Und das leidige Thema der views (und des non-propagating-const) mal>>> schön dargestellt:>>>> Na danke. Jetzt habe ich das Gefühl, dass die Standardisierungsgruppe>> komplett den Verstand verloren hat…>> Das gab es in der Vergangenheit auch schon mehrfach. man denke an> std::auto_ptr<> oder std::thread<>.
Soll das eine Ausrede sein? :D
Wer glaubt Views sein schon böse, der möge sich mal anschaun wie viel
Boilerplate man für eine Coroutine braucht...
Vincent H. schrieb:> Soll das eine Ausrede sein? :D
Nein, eine Feststellung.
> Wer glaubt Views sein schon böse, der möge sich mal anschaun wie viel> Boilerplate man für eine Coroutine braucht...
Da gibt es einen Unterschied: bei den coros braucht man zwar viel
Codierungsaufwand, jedoch funktioniert es mehr oder weniger wie
erwartet; und die coro-Baustelle ist definitiv noch nicht fertig. Es
folgen convenience-wrapper in den nä. Ausgaben des Standards.
Bei std::auto_ptr<>, std::thread<> und jetzt auch std::views<> ist es
broken-by-design bzw. broken-by-implementation.
Wilhelm M. schrieb:> Tja, Du kommst eben mindestens 4 Jahre zu spät ...
mag sein, aber wenn Dir das Thema am Herzen liegt (was nicht der Fall zu
sein scheint, wenn das Deine Antwort ist), dann macht man ein Update ...
so ist der ganze Thread Schrott und kann bzw. sollte geschlossen werden,
weil veraltet - aber der Moderation scheint das total egal zu sein.
Robert K. schrieb:> Wilhelm M. schrieb:>> Tja, Du kommst eben mindestens 4 Jahre zu spät ...> mag sein, aber wenn Dir das Thema am Herzen liegt (was nicht der Fall zu> sein scheint, wenn das Deine Antwort ist), dann macht man ein Update ...
Die Updates kommen hier als Posts, das solltest Du auch gemerkt haben.
> so ist der ganze Thread Schrott und kann bzw. sollte geschlossen werden,> weil veraltet - aber der Moderation scheint das total egal zu sein.
Viele hier stecken noch bei C++03/98 fest, oder beginnen gerade erst mit
C++11 oder halten compile-time-computation, etc. für Teufelszeug.
Wilhelm M. schrieb:>> Na danke. Jetzt habe ich das Gefühl, dass die Standardisierungsgruppe>> komplett den Verstand verloren hat…>> Das gab es in der Vergangenheit auch schon mehrfach. man denke an> std::auto_ptr<> oder std::thread<>.
Ich wäre an einen Link interessiert: Was ist das Problem mit thread<>?
Mikro 7. schrieb:> Wilhelm M. schrieb:>>> Na danke. Jetzt habe ich das Gefühl, dass die Standardisierungsgruppe>>> komplett den Verstand verloren hat…>>>> Das gab es in der Vergangenheit auch schon mehrfach. man denke an>> std::auto_ptr<> oder std::thread<>.>> Ich wäre an einen Link interessiert: Was ist das Problem mit thread<>?
Es ist kein RAI Typ. Wenn ein Thread das Scope verlässt und weder joined
noch detached is, dann gibts Probleme.
Wilhelm M. schrieb:> Die Updates kommen hier als Posts, das solltest Du auch gemerkt haben.
Wirklich? Dann sollte man wenigstens die toten Links entfernen ... das
kostet nur unnötig Zeit.
Wilhelm M. schrieb:> Viele hier stecken noch bei C++03/98 fest, oder beginnen gerade erst mit> C++11 oder halten compile-time-computation, etc. für Teufelszeug.
Beide Sprachen, also C wie auch C++ sind mehr oder weniger tot, weil
sich die Anwendungen und auch die Systemvoraussetzungen geändert haben -
wie haben jetzt 2023.
Man kann mit C++03 oder auch C99 vollkommen auskommen, aber aktuell sind
andere Sprachen angesagt, also sind C und C++ nur noch Nischen für
Alt-Programme ... für Reparatur irgendwelcher fehlgeschlagenen Projekte
und Anwendungen mit wenig Speicherplatz (also Mikrocontroller) macht C
als auch C++ noch Sinn - aber das war's dann auch schon.
Aus Nostalgie-Gründen sind beide Sprache eine schöne Sache, aber sonst
eine reine Nische ... und selbst die Nische fällt irgendwann weg, dann
ist es nur noch Nostalgie.
Vincent H. schrieb:> Mikro 7. schrieb:>> Wilhelm M. schrieb:>>>> Na danke. Jetzt habe ich das Gefühl, dass die Standardisierungsgruppe>>>> komplett den Verstand verloren hat…>>>>>> Das gab es in der Vergangenheit auch schon mehrfach. man denke an>>> std::auto_ptr<> oder std::thread<>.>>>> Ich wäre an einen Link interessiert: Was ist das Problem mit thread<>?>> Es ist kein RAI Typ.
RAII: ressource acquisition is initialization
std::thread ist schon ein RAII-like Ressourceverwalter, jedoch in
"ungewöhnlicher" Form. Das Problem hierbei ist, das der Zustand des
std::thread-Objektes extern bekannt sein muss, um den dtor korrekt
aufrufen zu können. Wird der dtor im Zustand "joinable" aufgerufen, dann
resultiert std::terminate. Dies ist broken-by-design, weil es auch die
exception-safety torpediert (Abrahams guarantees).
Weiterhin gibt es keine "einfache, eingebaute" Möglichkeit, den Thread
über std::thread (das Verwaltungsobjekt) abzubrechen.
Links dazu gibt es zu Hauf: google std::thread vs std::jthread
Naja, man muss beachten dass ein Thread eine doch sehr spezielle
Resource ist.
Wilhelm M. schrieb:> Wird der dtor im Zustand "joinable" aufgerufen, dann> resultiert std::terminate. Dies ist broken-by-design, weil es auch die> exception-safety torpediert (Abrahams guarantees).
Broken-by-design impliziert für mich ein Design-Problem. Das sehe ich
hier nicht. Der User kann ja den Thread detachen. Und für joinable
Threads einen Wrapper drum-herum setzen (mache ich bspw. so). Klar,
letzteres hätte die STL schon mitbringen können...
> Weiterhin gibt es keine "einfache, eingebaute" Möglichkeit, den Thread> über std::thread (das Verwaltungsobjekt) abzubrechen.
Existiert im Prozess mehr als ein Thread, dann kann ein Abbruch zu einem
undefinierten Prozesszustand führen. Das ist kein C++ Problem. Bekannte
Workarounds: Thread sich selbst beenden lassen; dedizierten Prozess
starten.
Mikro 7. schrieb:> Naja, man muss beachten dass ein Thread eine doch sehr spezielle> Resource ist.>> Wilhelm M. schrieb:>> Wird der dtor im Zustand "joinable" aufgerufen, dann>> resultiert std::terminate. Dies ist broken-by-design, weil es auch die>> exception-safety torpediert (Abrahams guarantees).>> Broken-by-design impliziert für mich ein Design-Problem. Das sehe ich> hier nicht. Der User kann ja den Thread detachen. Und für joinable> Threads einen Wrapper drum-herum setzen (mache ich bspw. so). Klar,> letzteres hätte die STL schon mitbringen können...
Wenn Du so argumentierst, braucht es std::thread gar nicht. Jeder kann
sich seine eigene Variante schreiben.
Ein Schnittstelle sollte leicht einfach und nicht schwer falsch zu
benutzen sein.
>> Weiterhin gibt es keine "einfache, eingebaute" Möglichkeit, den Thread>> über std::thread (das Verwaltungsobjekt) abzubrechen.>> Existiert im Prozess mehr als ein Thread, dann kann ein Abbruch zu einem> undefinierten Prozesszustand führen. Das ist kein C++ Problem.
In der Art wie std::thread existiert, ist es schon ein C++ Problem.
> Bekannte> Workarounds: Thread sich selbst beenden lassen
Und genau das realisiert std::jthread. Problem gelöst in einer
standardisierten Variante.
Wilhelm M. schrieb:> Wenn Du so argumentierst, braucht es std::thread gar nicht. Jeder kann> sich seine eigene Variante schreiben.
Das gehst du ein bisschen zu weit. Vorher gab es in C++ gar keine
Threads.
Mehr zum Thema, wen es interessiert, von Nicolai in einer Keynote:
https://www.youtube.com/watch?v=elFil2VhlH8
Da spricht er dann tatsächlich von einem Design Problem (wegen RAII).
-.-
War mir so nie aufgefallen da ich Threads zum Pool und Exception
Handling eh kapsele.
Mikro 7. schrieb:> Wilhelm M. schrieb:>> Wenn Du so argumentierst, braucht es std::thread gar nicht. Jeder kann>> sich seine eigene Variante schreiben.>> Das gehst du ein bisschen zu weit.
Keineswegs.
> Vorher gab es in C++ gar keine> Threads.
Man konnte schon immer das API des OS benutzen ;-)
Beitrag "Re: C++ in (deeply) Embedded Systemen für Neuprojekte"
In diesem Thread hatte ich geschrieben:
Meine Zutaten zur embedded Programmierung sind im Moment:
templates, scoped enums, meta programming, type_traits, requires,
concepts also C++20.
Ich muss es zuerst das embedded ein wenig einschränken, ich meine damit
den reinen Hardware Zugriff über dedizierte Register. Embedded
Algorithmen und Datenstrukturen sind damit nicht gemeint. Dafür ist die
std Library da.
Also warum ?
Das übliche : void write_reg (unsigned regaddress, unsigned regvalue);
hat verschiedene Probleme. Als Parameter wird jeder unsigned int-wert
und alles was der Compiler automatisch automatisch konvertiert
akzeptiert (z.B. unscoped enums). Auch die Parameter können vertauscht
werden. Compiler, Assembler und auch externe Tools können nichts dagegen
tun. Man kann das alles ein wenig durch Vorschriften einschränken aber
nicht sicher machen und es kann zu Laufzeitfehlern führen.
Klassisches C++ kennt Signaturen, das hilft aber in diesem Falle auch
nichts (sind ja alles unsigned int). Also brauchen wir etwas das aus
einem individuellen int einen Datentyp macht. Da kommen die Templates
ins Spiel
und auch gleich die type_traits ;-) zum testen . Und weil wir den
Laufzeitcode nicht aufblähen wollen lassen wir das alles zu Compilzeit
machen ( meta-programming). Es werden also nur Template Instanzen und
consteval functions erzeugt
<C>
#include <stdint.h>
#include <type_traits>
template< unsigned v>
struct uint_wrapper {
static constexpr unsigned val =v;
};
int main() {
// return std::is_same_v<int_wrapper<5>,int_wrapper<5> >; // true
return std::is_same_v<uint_wrapper<3>,uint_wrapper<5> >; // false
}
</C>
ARM GCC 11 erzeugt folgenden code
main:
mov r0, #0 bzw #1 wenn true
bx lr
Der nächste Schritt wir machen das ganze generisch
<c>
template< T v>
struct wrapper {
static constexpr T val = v;
}
</c>
Damit schaffen wir uns ein neues Problem ein double oder String macht
als Registeradresse wenig Sinn. Wir müssen den generischen Typ auf
sinnvolle Typen begrenzen und dann sind wir auch schon bei requires
und damit können wir auch die Values auf zulässige Werte begrenzen.
Fazit wir können uns eigene Anwendungs-Domain Datentypen schaffen.
Template strukturen können auch erben und man kann über die type_traits
abfragen von wem sie abstammen. Man kann Template Strukturen mit
zusätzlichen statischen Parametern versorgen wie z.B. Versionsnummern.
scoped enums erzeugen auch einen eindeutigen Datentyp, der erhalten
bleibt und nicht automatisch nach dem underlying type gecastet wird wenn
er als Parameter übergeben wird.
Es ist auch möglich damit eigene type_traits zu schreiben und die
spezialisierung der templates für das Endprodukt zu steuern. usw. usw
Und manchmal muss man sich entscheiden andere Wege wie die std library
zu gehen weil man auf die gegebene Hardware angewiesen ist und die hat
weniger Freiheiten wie Softwarekonzepte.
Anbei noch ein snippet wo ich mit scoped enums und templates ohne
requires und concepts mal angefangen habe einen STM32F Timer bis
herunter zu den register-field-values zu modelieren. Leider sind die
zulässigen field values nicht in den svd files definiert und alles muss
man aus den datenblätter lesen. Der Rest lässt sich so ziemlich
automatisch generieren.
Hans-Georg L. schrieb:> Das übliche : void write_reg (unsigned regaddress, unsigned regvalue);> hat verschiedene Probleme. Als Parameter wird jeder unsigned int-wert> und alles was der Compiler automatisch automatisch konvertiert> akzeptiert (z.B. unscoped enums).
Mehrstellige Funktionen mit Parametern derselben Typen ist immer eine
schlechte Idee!!! Das sind Basics.
> Auch die Parameter können vertauscht> werden. Compiler, Assembler und auch externe Tools können nichts dagegen> tun. Man kann das alles ein wenig durch Vorschriften einschränken aber> nicht sicher machen und es kann zu Laufzeitfehlern führen.
Man braucht keine Vorschriften ...
> Klassisches C++ kennt Signaturen, das hilft aber in diesem Falle auch> nichts (sind ja alles unsigned int).
Doch.
> Also brauchen wir etwas das aus> einem individuellen int einen Datentyp macht. Da kommen die Templates> ins Spiel
Dazu braucht es keine Templates.
Es reicht:
1
voidwrite_reg(Addressa,uint32_tvalue);
> und auch gleich die type_traits ;-) zum testen . Und weil wir den> Laufzeitcode nicht aufblähen wollen lassen wir das alles zu Compilzeit> machen ( meta-programming).
Unter TMP wird schon ein wenig mehr verstanden.
Und wenn value nur 1, 2 oder 3 sein darf?
Das Problem ist eher das man für die komplexe Peripherie eines H7 zB
nicht alles selber neu erfinden möchte. Und HAL benutzt als kleinsten
gemeinsamen Nenner ‚nur‘ C.
Wilhelm M. schrieb:> Hans-Georg L. schrieb:>> Das übliche : void write_reg (unsigned regaddress, unsigned regvalue);>> hat verschiedene Probleme. Als Parameter wird jeder unsigned int-wert>> und alles was der Compiler automatisch automatisch konvertiert>> akzeptiert (z.B. unscoped enums).>> Mehrstellige Funktionen mit Parametern derselben Typen ist immer eine> schlechte Idee!!! Das sind Basics.>
findest du aber in sehr vielen Programmen. Das es schlecht ist sind wir
einer Meinung
>> Auch die Parameter können vertauscht>> werden. Compiler, Assembler und auch externe Tools können nichts dagegen>> tun. Man kann das alles ein wenig durch Vorschriften einschränken aber>> nicht sicher machen und es kann zu Laufzeitfehlern führen.>> Man braucht keine Vorschriften ...>>> Klassisches C++ kennt Signaturen, das hilft aber in diesem Falle auch>> nichts (sind ja alles unsigned int).>> Doch.>>> Also brauchen wir etwas das aus>> einem individuellen int einen Datentyp macht. Da kommen die Templates>> ins Spiel>> Dazu braucht es keine Templates.> Es reicht:>>
1
>voidwrite_reg(Addressa,uint32_tvalue);
2
>
>
Einfach Address ist kein Schlüsselwort oder Datentyp.
Und eine Möglichkeit aus einem einfachen int einen datentyp zu machen
ist über ein struct template. Gut der Zusammenhang zu dem write_reg
fehlt bei mir.
>> und auch gleich die type_traits ;-) zum testen . Und weil wir den>> Laufzeitcode nicht aufblähen wollen lassen wir das alles zu Compilzeit>> machen ( meta-programming).>> Unter TMP wird schon ein wenig mehr verstanden.
Das ist doch auch klar
Ich wollte einfach zu jedem Begriff den ich geschrieben habe ein
Beispiel geben, keine erschöpfende Abhandlung schreiben und möglichst
verständlich für Anfänger bleiben.
J. S. schrieb:> Und wenn value nur 1, 2 oder 3 sein darf?
dann nimmst du anstelle uint32_t ein (scoped) enum.
> Das Problem ist eher das man für die komplexe Peripherie eines H7 zB> nicht alles selber neu erfinden möchte. Und HAL benutzt als kleinsten> gemeinsamen Nenner ‚nur‘ C.
Das ist ja das Problem für so einen Boliden etwas eigenes zu schreiben
kostet wahnsinnig viel Zeit.
Aus eigener Erfahrung ... wenn es komplizierter wird kannst du dich auf
die HAL und den von CubeMX erzeugten Code auch nicht immer verlassen ...
Fehlersuche kostet auch viel Zeit.
Hans-Georg L. schrieb:> Das ist ja das Problem für so einen Boliden etwas eigenes zu schreiben> kostet wahnsinnig viel Zeit.
Etwas eigenes zu schreiben wäre nicht nötig, wenn es etwas brauchbares
gäbe und eine Community vorhanden wäre. Deshalb zieht Arduino die Massen
so magisch an.
Ich kenne zwei brauchbare "c++ Template-Boliden". Einer ist etwas älter
und einfacher, der andere sehr aktuell aber offenbar geheim. Normale
Programmierer nutzen Werkzeuge die verfügbar und verständlich sind.
Ohne Grundgerüst, nur mit Stichworten und Hinweisen wird das nix. So
bleibt ein tolles Werkzeug Spielwiese für einige hochbegabte Experten.
Das Code-Snippet von Hans-Georg L. zeigt in die richtige Richtung.
Es braucht aber ein funktionierendes c++ Gerüst mit templates/concepts,
das auf Source-Code Ebene die Abstraktion sichtbar und auch begreifbar
macht und anhand von Beispielen die Anwendung erklärt. Mehr kommt von
selber, wenn das Interesse einmal geweckt ist ..
Andernfalls bleibt es akademisch.
Wilhelm M. schrieb:> Hans-Georg L. schrieb:>> Einfach Address ist kein Schlüsselwort oder Datentyp.>> Was? Natürlich ist Address ein DT, eben ein UDT.
Wo und wie ist er bitte definiert ? cppreference.com kennt ihn nicht.
Entweder wir reden aneinander vorbei, oder auf verschiedenen Ebenen,
oder ich steh einfach auf dem Schlauch ;-)
Hans-Georg L. schrieb:> Wilhelm M. schrieb:>> Hans-Georg L. schrieb:>>> Einfach Address ist kein Schlüsselwort oder Datentyp.>>>> Was? Natürlich ist Address ein DT, eben ein UDT.> Wo und wie ist er bitte definiert ? cppreference.com kennt ihn nicht.
Natürlich nicht, ich schrieb ja auch UDT = user-defined-type.
1
structAddress{
2
constuint32_tvalue;
3
};
> Entweder wir reden aneinander vorbei, oder auf verschiedenen Ebenen,> oder ich steh einfach auf dem Schlauch ;-)
Schlauch.
1
voidwrite(Address,uint32_t);
2
3
...
4
5
write(Address{0x100},42);
Wenn Du willst, kannst Du die Parameterliste auch permutieren. Dann geht
auch:
Wilhelm M. schrieb:> Hans-Georg L. schrieb:>> Wilhelm M. schrieb:>>> Hans-Georg L. schrieb:>>>> Einfach Address ist kein Schlüsselwort oder Datentyp.>>>>>> Was? Natürlich ist Address ein DT, eben ein UDT.>> Wo und wie ist er bitte definiert ? cppreference.com kennt ihn nicht.>> Natürlich nicht, ich schrieb ja auch UDT = user-defined-type.>>
1
>structAddress{
2
>constuint32_tvalue;
3
>};
4
>
>>> Entweder wir reden aneinander vorbei, oder auf verschiedenen Ebenen,>> oder ich steh einfach auf dem Schlauch ;-)>> Schlauch.>>
1
>voidwrite(Address,uint32_t);
2
>
3
>...
4
>
5
>write(Address{0x100},42);
6
>
>> Wenn Du willst, kannst Du die Parameterliste auch permutieren. Dann geht> auch:>>
1
>write(42,Address{0x100});
2
>
Da sind wir doch schon wieder beieinander ;-)
Die write_reg funktion stammt aus C-code, das habe ich nicht explizit
geschrieben OK.
Die "Arbeit" der Typwandlung macht die struct, dazu ist kein template
notwendig. Ok
Das Template brauche ich erst wenn ich Adressen parametrieren möchte und
getrennte Datentypen für verschiedene Adressen haben will. Das war die
Absicht siehe: is_same in main ;-)
noch Einwände oder Fragen ?
Hans-Georg L. schrieb:> Die write_reg funktion stammt aus C-code, das habe ich nicht explizit> geschrieben OK.
Zumindest habe ich es nicht gelesen!
> Das Template brauche ich erst wenn ich Adressen parametrieren möchte und> getrennte Datentypen für verschiedene Adressen haben will.
Ja, kann man machen.
> Das war die> Absicht siehe: is_same in main ;-)
Das Beispiel sagt nur, dass Du std::integral_constant<> halb nachgebaut
hast.