Mark W. schrieb:> Ich bin gerade dabei fuer 30 ifs aus 150 Zeilen 30 zu machen.
was genau spart man, wenn man Zeilen spart?
Hast Du eine überempfindliche Return-Taste?
Mark,
falls du bei mir als Software-Entwickler arbeiten würdest, würde ich
dich allein für die Frage entlassen.
Du sparst keine Lesearbeit, du machst Arbeit. Warum denkt jeder
Programmmierer er wäre eine special Snowflake und besser als der
Compiler?
1. Schreib was du meinst
2. Verlass dich auf den Compiler
3. verwende in dem Projekt autoformat
4. das ganze soll geunit-tested werden
Mark W. schrieb:> schreibt Ihr auch gelegentlich mal Code, nur um Zeilen zu sparen?> Oder geht das gar nicht?
möchte ich zeilen sparen, schreibe ich gar keinen code...
asdf schrieb:> Mark,>> falls du bei mir als Software-Entwickler arbeiten würdest, würde ich> dich allein für die Frage entlassen.>
Ooops. Naja, zum Glueck bin ich ja kein Software-Entwickler.
War auch nicht so ernst gemeint, wollte nur mal sehen was die Fachleute
dazu sagen.
Ging mir hier um die Uebersichtlichkeit, weil man da beim Schreiben
weniger scrollen muss.
Cool schrieb:> Ich wusste nichtmal dass man mit Switch Bereiche testen kann
Kann man auch regulär nicht, da dies nicht zum C-Standard gehört.
Bestimmte Compiler wie der gcc unterstützen dies als eine Erweiterung.
asdf schrieb:> Du sparst keine Lesearbeit, du machst Arbeit. Warum denkt jeder> Programmmierer er wäre eine special Snowflake und besser als der> Compiler?>> 1. Schreib was du meinst> 2. Verlass dich auf den Compiler> 3. verwende in dem Projekt autoformat> 4. das ganze soll geunit-tested werden
Fachlich eine sehr gute Antwort.
Aber das...
asdf schrieb:> falls du bei mir als Software-Entwickler arbeiten würdest, würde ich> dich allein für die Frage entlassen.
...ist ein ziemlich klingonischer Ansatz. Wenn Du über die Entlassung
von Mitarbeiter zu entscheiden hättest und tatsächlich so entscheiden
würdest (sprich: bei allen Fragen, Gedanken, Überlegungen der Kollegen,
die Du spontan dumm findest), wärst Du sehr schnell eine One-Man-Show.
Mark W. schrieb:> asdf schrieb:>> Mark,>>>> falls du bei mir als Software-Entwickler arbeiten würdest, würde ich>> dich allein für die Frage entlassen.>>> Ooops. Naja, zum Glueck bin ich ja kein Software-Entwickler.> War auch nicht so ernst gemeint, wollte nur mal sehen was die Fachleute> dazu sagen.> Ging mir hier um die Uebersichtlichkeit, weil man da beim Schreiben> weniger scrollen muss.
Also nur getrolle. Moderatoren: Thread und User können weg.
> Ich wusste nichtmal dass man mit Switch Bereiche testen kann
Wie schon geschurbt wurde ist das non-standard. Würde hierzufirma wohl
auch (berechtigterweise) zum Rauswurf führen.
Mark W. schrieb:> Hallo,>> schreibt Ihr auch gelegentlich mal Code, nur um Zeilen zu sparen?> Oder geht das gar nicht?
Man kann alles machen - wenn man es sinnvoll begründen kann.
"Zeilen sparen" ist selten ein sinnvolles Argument. Für nicht
verwendeten Speicherplatz bei den Sourcecode-Dateien gibt es kein Geld
zurück. ;-)
Markus F. schrieb:> Mark W. schrieb:>> Ich bin gerade dabei fuer 30 ifs aus 150 Zeilen 30 zu machen.>> was genau spart man, wenn man Zeilen spart?>
Naja, ich finde es wird uebersichtlicher. Man hat mehr Code auf dem
Bildschirm und da es sich immer um die gleich Funktionalitaet handelt,
sieht man Fehler leichter, weil es eben symmetrischer ist.
Aber das ist ja relativ, verstehe schon, dass die Fachleute sich da an
geltende Standards halten sollten, speziell wenn man im Team arbeitet.
Bei mir schaut da keiner hin, ist nur privat.
Ok schrieb:> Also kurzer unleserlicher Code soll besser sein als Leserlicher bei dem> man länger scrollen muss...
Hmm, wenn ich mir das genau ueberlege, wer sagt denn dass es unleserlich
sein muss.
Wenn ich mein Beispiel nehme, dann wuerde ich das auch nach einem halben
Jahr noch verstehen.
Übersichtlich wird es, wenn man solche Monster-Abfragen in eine Funktion
wegräumt und die 150 Zeilen durch eine ersetzt:
1
calc_ou(output_mv,&o,&u);
Wenn in dieser Funktion, die nur eine Sache erledigt, 150 ähnliche
Zeilen stehen, stört das keinen. Die Testbarkeit wurde schon erwähnt.
Wenn man die Grenzen ständig anpasst, würde ich den Sourcecode dieser
Funktion generieren lassen, um Fehler zu vermeiden.
---------------------------------------
1
if(output_mV<100......
2
if(output_mV>99......
Die Grenzen so zu schreiben ist maximal verwirrend, weil für jede Grenze
zwei verschiedene Zahlen da stehen. Bei der nächsten Anpassung ändert
man die 100 und übersieht wahrscheinlich, dass die 99 auch hätte
geändert werden müssen. Hätte man
1
if(output_mV<100.........
2
if(output_mV>=100........
geschrieben, wäre das aufgefallen. Die verbreitete Aversion gegen <= und
>= erschließt sich mir nicht.
---------------------------------------
Mark B. schrieb:> "Zeilen sparen" ist selten ein sinnvolles Argument.
Wenn man eine Aversionen gegen die Benutzung von Funktionen hat, schon.
Wenn ich nur so ganz kurze Anweisungen habe, schreibe ich auch mal ein
if in eine Zeile, aber spätestens wenn ich mal den code beautifyer
starte, habe ich eh wieder mehrer Zeilen.
Außerdem gibts ja auch Code-Folding, falls man möglichst viel auf einmal
sehen muss.
Ivo
Die zweifach hingeschriebenen Grenzen kann man sich auch mit sinnvoll
plazierten elses sparen, wenn wie im Beispiel nur eine Zahl in
Wertebereiche eingeordnet werden soll:
Peter D. schrieb:> Rekursion mit variabler Argumentenliste, da kriegt man ja ne Knoten im> Gehirn.
Absolut gängige Praxis bei funktionaler Programmierung. So kann der
Aufrufer mit wenig Code eine konsistente Bereichs-Abfrage bauen. Auf
Wunsch fügt man noch eine Prüfung aufs Minimum hinzu.
Dr. Sommer schrieb:> Absolut gängige Praxis bei funktionaler Programmierung.
Wenn ich das richtig sehe, ist die Abbruchbedingung der Rekursion das
Fehlen weiterer Argumente.
Kann der Compiler sowas aufdröseln oder packt er wirklich zur Laufzeit
den gesamten Wust an Argumenten auf den Stack?
Peter D. schrieb:> Wenn ich das richtig sehe, ist die Abbruchbedingung der Rekursion das> Fehlen weiterer Argumente.
Richtig, aber die Bedingung wird beim Compilieren ausgewertet, nicht zur
Laufzeit. Die Aufruftiefe ist also fix.
Peter D. schrieb:> Kann der Compiler sowas aufdröseln oder packt er wirklich zur Laufzeit> den gesamten Wust an Argumenten auf den Stack?
Nur wenn nicht geinlined wird. Wenn man sichergehen möchte dass alles
geinlined wird schreibt man noch ein "__attribute__((always_inline))
inline" dran. Dann wird daraus praktisch eine simple if-else-Kette.
Was gefällt dir nicht an der Lösung, die schon weiter oben gepostet
wurde?
militanter Zeilensparer schrieb:> o = (output_mv / 100) * 2 + 4;> u =o + 1;
(ich hab sie mal leicht abgeändert, weil vorher imho eine Zahl nicht
exakt gestimmt hat)
Wenn deine 30 folgenden ifs alle so schön regelmäßig weiterzählen wie
die ersten drei, dann lässt sich das doch alles zu dieser einfachen
Formel zusammenfassen.
Achim S. schrieb:
> militanter Zeilensparer schrieb:>> o = (output_mv / 100) * 2 + 4;>> u =o + 1;
Habe ich gesehen. Habe nur noch nicht drauf geantwortet. Will ich morgen
mal ausprobieren.
Mark W. schrieb:> Naja, ich finde es wird uebersichtlicher.
Kann, muss nicht.
Damit es übersichtlicher wird, müsste es wirklich alles auch schön
formatiert werden, dass es am Ende wie eine Tabelle aussieht. In
solchen Fällen benutze ich sowas auch gelegentlich.
Der Gewinn an Lesbarkeit dadurch muss aber schon erheblich sein,
damit die Maßnahme gerechtfertigt ist.
ps: Das beißt sich dann natürlich mit der Überschrift, die du diesem
Thread gegeben hast. ;-) Wenn es dadurch wirklich "unleserlich"
wird, ist es niemals gerechtfertigt.
asdf schrieb:> 2. Verlass dich auf den Compiler
Dass man damit keinen Objektcode einspart, war wohl auch dem TE von
vornherein klar und in keiner Weise die Absicht.
Ivo Z. schrieb:> spätestens wenn ich mal den code beautifyer starte
Einem solchen kann man normalerweise auch sagen, dass er bestimmte
Bereiche, die sorgsam manuell formatiert worden sind, nicht anfassen
soll.
Mark W. schrieb:> schreibt Ihr auch gelegentlich mal Code, nur um Zeilen zu sparen?> Oder geht das gar nicht?> if(output_mV < 100){o = 4; u = 5;}
Habe ich früher mal gemacht. Dann hat man aber ein Problem, wenn man den
Code schrittweise im Debugger durchgeht. Denn typischerweise springt der
Debugger beim Single-Stepping über die ganze Zeile drüber, egal ob die
Bedinung wahr oder falsch war. Um zu sehen, ob der Branch betreten
worden ist oder wäre, muss man sich also vorher und nachher die
Variablenwerte ansehen.
Schreibt man hingegen
1
if(output_mV<100){
2
o=4;
3
u=5;
4
}
dann sieht man beim Single-Stepping ganz klar, ob der Branch betreten
wird oder nicht.
Deshalb schreibe ich schon lange keine kompakten if-Einzeiler mehr.
Mark B. schrieb:> "Zeilen sparen" ist selten ein sinnvolles Argument. Für nicht> verwendeten Speicherplatz bei den Sourcecode-Dateien gibt es kein Geld> zurück. ;-)
"Zeilen sparen" kann aber ein sinnvolles Argument sein, wenn man dafür
eine Funktion komplett auf den Bildschirm bekommt, statt viel scrollen
zu müssen. Da muss man abwägen, was man nun besser lesbar findet: Alles
schön sauber in einzelne Zeilen geschrieben, dafür so, dass man ständig
scrollen muss, oder eher kompakt, dafür ist aber alles auf einen Blick
zu sehen. Für mich muss Variante 1 nicht zwingend und unumstößlich das
Optimum sein, auch wenn es hier Leute gibt, die das als Grund sehen
würden, jemanden auf die Straße zu setzen…
Ich würde es dann sauber untereinander schreiben, passend zu einander
eingerückt:
1
if(output_mV<100){o=4;u=5;}
2
if(output_mV>99&&output_mV<200){o=6;u=7;}
3
if(output_mV>199&&output_mV<300){o=8;u=9;}
4
if(output_mV>299&&output_mV<400){o=10;u=11;}
So finde ich das besser lesbar und schneller erfassbar, als wenn da jede
Klammer und jede Zuweisung ihre eigene Zeile bekommt. Und die
angegebenen 30 Zeilen passen komplett auf den Bildschirm, die 150 eher
nicht, was die Übersicht weiter verbessert.
Die vorher genannten Argumente, statt > 99 lieber >= 100 zu schreiben
oder gleich else zu nutzen, um sich jeweils die Untergrenze zu sparen,
sind auch sinnvoll.
Ivo Z. schrieb:> Außerdem gibts ja auch Code-Folding, falls man möglichst viel auf einmal> sehen muss.
Gerade das tut man bei Code-Folding ja nicht. Um zu erkennen, ob alle
Zuweisungen an o und u richtig sind, muss ich erst sämtliche Folds
öffnen.
tictactoe schrieb:> dann sieht man beim Single-Stepping ganz klar, ob der Branch betreten> wird oder nicht.
Bei üblicher brauchbarer Optimierung greift dieses Argument jedoch
so gut wie nicht. Wirklich zeilenweises Abarbeiten funktioniert nur,
wenn man nicht optimiert.
Rolf M. schrieb:> Ich würde es dann sauber untereinander schreiben, passend zu einander> eingerückt:> if ( output_mV < 100) { o = 4; u = 5; }> if (output_mV > 99 && output_mV < 200) { o = 6; u = 7; }> if (output_mV > 199 && output_mV < 300) { o = 8; u = 9; }> if (output_mV > 299 && output_mV < 400) { o = 10; u = 11; }
Ich auch, aber die Reihenfolge umdrehen und was weglassen:
1
if(output_mV<400){o=10;u=11;}
2
if(output_mV<300){o=8;u=9;}
3
if(output_mV<200){o=6;u=7;}
4
if(output_mV<100){o=4;u=5;}
Ob die bei kleinen Werten erfolgende wiederholte Zuweisung günstiger ist
als die Bereichsprüfung bei den größeren? Keine Ahnung, müsste man bei
zeitkritischen Bedingungen mal überlegen bzw. anschauen.
Solche "Zeilensparumstellungen" finde ich nur ok für die ersten paar
Zeilen (in TE Bsp: keinesfalls alle 30 ifs) und zwar als Schuhlöffel um
dem Gehirn bei der Mustererkennung auf die Sprünge zu helfen.
Letztlich muss solcher "tabellarisch datengesteuerter Code" nicht aus 30
ifs bestehen sondern aus einer Schlaufe und einer (inlined?) Funktion
welche sich durch die Wertetabelle arbeitet. Also wenn es sich nicht
direkt berechnen lässt wie militanter Zeilensparer es zeigt.
30 ifs erfordern streng genommen (mindestens!) n*30 Testcases welche
Niemand schreiben/pflegen/kontrollieren/protokollieren will. Für jede
neue Übersetzung durch den Compiler!
Die Schlaufe + Funktion ist hingegen mit 1..2 Handvoll Testcases
abgedeckt, ja sie kann sogar als binary wiederverwendet werden (lib zum
linken) und muss nie wieder nachgetestet werden auch wenn die
Parametertabelle andere Werte bekommt.
Dieser Gedankenablauf muss eigentlich schon stattfinden bevor 30 ifs
auf je mehreren Zeilen darniedercodiert werden... (ich hätte den Fleiß
dazu schon gar nicht, ich kann ja Programmieren und nicht nur nach
Diktat Code ergießen)
Achim S. schrieb:> militanter Zeilensparer schrieb:>> o = (output_mv / 100) * 2 + 4;>> u =o + 1;
Fantastisch.
Ich habe es jetzt so gemacht und es funktioniert. Es brauch nicht einmal
ein if Anweisung.
Gestern hatte ich ueberlegt und habe es nicht 100% verstanden wegen der
Rundung. Aber da o und u int sind und alles nach dem Komma wegfaellt
geht's wunderbar.
Auch alle anderen Vorschlaege haben meinen Horizont erweitert. :-)
militanter Zeilensparer schrieb:> if (output_mv >= 400) {> u = o = 0;> } else {> o = (output_mv / 100) * 2 + 2;> u =o + 1.;> }
Militanter Deleygenerator.
Auf nem µC dauern die div 100 deutlich länger als die paar if-Abfragen.
Karl schrieb:> Auf nem µC dauern die div 100 deutlich länger als die paar if-Abfragen.
Kennst du nur AVR? Schon Cortex m3 haben ein div in Hardware.
Die direkte Berechnung hat aber einen viel wichtigeres
Karl schrieb:> Oder man sucht ganz einfach in einer lut.
This.
Programmiersprachentheaterintendant schrieb:> Letztlich muss solcher "tabellarisch datengesteuerter Code" nicht aus 30> ifs bestehen sondern aus einer Schlaufe und einer (inlined?) Funktion> welche sich durch die Wertetabelle arbeitet.
And this. Nur deutlich besser ausgedrückt.
Aber gut, ich komme aus dem Automotive Bereich. Da würde man
gesteinigt für eine if Kaskade. Allein schon, weil man die daten zur
Laufzeit andern können muss.
Mark W. schrieb:> Hallo,>> schreibt Ihr auch gelegentlich mal Code, nur um Zeilen zu sparen?> Oder geht das gar nicht?
Dein zu lösendes Problem besteht doch darin, in einer Menge von
rechts-offenen Intervallen das Intervall zu finden, das einen bestimmten
Wert beinhaltet. Und dieses Intervall möchtest Du durch einen Index
kennzeichnen.
Die Frage ist, warum willst Du bei Deiner Lösung Zeilen sparen?
Vermutlich, weil er unleserlich (geworden) ist.
Wann wird Code unleserlich? Wenn (zu) viel imperativ gemacht wird (wie
bei Dir).
Deswegen gibt es ja auch die Empfehlungen:
a) benutze Algorithmen / Funktionen, keine expl. Iterationen
b) benutze Algorithmen / Funktionen, keine expl. Alternativen
Diese Empfehlungen führen zu deklarativem Code, und der ist in den Augen
vieler besser lesbar, wartbar, testbar.
Code ist dann verständlich, wenn man explizit hinschreibt, WAS gemacht
werden soll, aber nicht das WIE.
Natürlich muss man irgendwo einen Algorithmus schreiben, der die o.g.
Intervalle konstruiert oder das Lookup durchführt. Dazu sind Iterationen
und Alternativen notwendig. Wenn man die in seinem Anwendungscode nicht
mehr haben will, gibt es nur die Möglichkeit, sie nach unten (oder
manchmal auch nach oben) in der Abstraktionsschicht zu schieben.
@Wilhelm M.
Ja das ist ganz nett, insbesondere da ich auch gerade mal wieder etwas
C++ lerne...
Aber wie ist denn der daraus erzeugte Assembler code? Wirklich gleich
gut optimiert als wie die ursprünglichen C Anweisungen? Bei uC ist das
ja schon relevant, und sonnst eigentlich auch.
Stefan schrieb:> @Wilhelm M.>> Ja das ist ganz nett, insbesondere da ich auch gerade mal wieder etwas> C++ lerne...>> Aber wie ist denn der daraus erzeugte Assembler code? Wirklich gleich> gut optimiert als wie die ursprünglichen C Anweisungen? Bei uC ist das> ja schon relevant, und sonnst eigentlich auch.
Habe es nicht ausprobiert, aber ich gehe davon aus, dass der mindestens
so gut wie die C Variante ist.
Das liegt daran, dass hier
1) die Intervalle constexpr sind, d.h. sie werden schon zur Compilezeit
berechnet, und
2) Funktionstemplates ja immer inline-Kandidaten sind, denn ihre
Definitions ist dem Compiler immer bekannt (template-header-only-libs
haben immer diesen Vorteil), so dass die Inline-Heuristiken immer
angewendet werden.
Markus F. schrieb:> warum nicht einfach per Lookup-Table?
Das macht der Code, den ich gepostet hatte ja.
> Dann kann man die Parameter auch noch zur Laufzeit ändern, falls> notwendig.>>
Mmh, da fallen mir gleich mehrere Sachen ein, warum das nicht gut ist:
1) der Sentinel (0) in der LUT zu verwenden ist sehr gefährlich
2) woraus kann man die Art des Intervalls (geschlossen, links-offen,
rechts-offen) erkennen? Unklar.
3) globale Variablen (als return) (war hoffentlich ein Versehen)
4) in vielen Fällen ist der Datentyp int in der LUT nicht passend
5) der Typ der Iterationsvariable i als int ist auch ungünstig
6) der Code ist nicht allgemeingültig:
6a) der Name ist schlecht gewählt
6b) kann nur mit int's arbeiten
Stefan schrieb:> Mark W. schrieb:>> Ich bin gerade dabei fuer 30 ifs aus 150 Zeilen 30 zu machen.>> In diesem konkreten Fall kann man auch fünf daraus machen, etwa>>
1
> let range = output_mV div 100
2
> var o = range + 5
3
> if range == 0:
4
> dec(o)
5
> let u = o + 1
6
>
>> Zunächst den Bereich auf Integer-Werte abzubilden ist immer eine gute> Idee, dann kann man die benötigten Zahlenwerte einfach in einem ARRAY> ablegen.
Auch das halte ich für nicht gut:
1) das geht nur für reguläre, benachbarte Intervalle
2) auch hier ist die Art des Intervalls unklar bzw. im Code versteckt.
3) imperativer Code, der seine Bedeutung schlecht offenbart, weil in
einzelnen Statements versteckt.
4) well, basic ...
Wilhelm M. schrieb:> Auch das halte ich für nicht gut:
Nö gut nicht unbedingt, daher schrieb ich ja auch
>In diesem konkreten Fall kann man auch fünf daraus machen, etwa
Man sollte halt nur wissen dass man es machen kann. Wenn man sicher ist,
dass das Schema diese konkrete Form beibehält, so ist es nicht unbedingt
schlecht und liefert guten ausführbaren Code. Und der Fall, dass man aus
einem Integer-Ausgangswert einfach Indizes 0, 1, 2, ... machen kann
kommt nicht so selten vor, dann kann man damit leicht auf eine Tabelle
in Form eines Arrays zugreifen.
Wilhelm M. schrieb:> if ((value >= 0) && (value < 10)) {> result = 0;
Da value ein uint8_t ist, trifft die Bedingung >= 0 immer zu.
In den folgenden Else-Zweigen ist der >= -Vergleich jeweils überflüssig,
denn wenn die Bedingung nicht zutrifft, trifft der jeweils vorhergehende
Vergleich zu.
Damit fällt
Das sind dann immer zusammenhängende, also angrenzende Intervalle. Und
das erste Intervall ist [-INT_MAX, 10[.
Ich bin mir nicht sicher, ob das beim TO immer gegeben ist. Und falls
man von der impliziten Sortierung abweicht, wird es falsch.
Rufus Τ. F. schrieb:> Wilhelm M. schrieb:> Und das erste Intervall ist [-INT_MAX, 10[.>> Nein. Welchen Datentyp hat "value"?
Selbst wenn es int wäre, wäre -INT_MAX nicht das Minimum... Außer auf
Plattformen die das 1er-Komplement nutzen.
Rufus Τ. F. schrieb:> Wilhelm M. schrieb:>> Und das erste Intervall ist [-INT_MAX, 10[.>> Nein. Welchen Datentyp hat "value"?
Ja stimmt: ich hatte es vorher mit int geschrieben ...
Und natürlich wird der unnötige Vergleich vom Compiler wegoptimiert.
Der exemplarische C-Code war eher dazu gedacht, die Analogie zum
generischen Code darzustellen.
Dr. Sommer schrieb:> Rufus Τ. F. schrieb:>> Wilhelm M. schrieb:>> Und das erste Intervall ist [-INT_MAX, 10[.>>>> Nein. Welchen Datentyp hat "value"?>> Selbst wenn es int wäre, wäre -INT_MAX nicht das Minimum... Außer auf> Plattformen die das 1er-Komplement nutzen.
Stimmt auch. Bezogen auf int natürlich [INT_MIN, 10[.
Und es gibt noch einen Unterschied: da die Parameterübergabe an die
lookup<>() Funktion per-value erfolgt, wird das volatile nur einmal
gelesen. Im C-Code erfolgt der Zugriff dementsprechend in jedem if-stmt.
Wenn das nicht gewollt ist, dann sollte man in C auch eine Funktion
schreiben und die Intervallgrenzen als Array übergeben (wurde oben schon
mal gepostet mit dem Problem des sentinels) oder eben:
militanter Zeilensparer schrieb:> if (output_mv >= 400) {> u = o = 0;> } else {> o = (output_mv / 100) * 2 + 2;> u =o + 1.;> }
Du bist noch nicht militant genug:
u = o = 0;
if (output_mv < 400) {
o = (output_mv / 100) * 2 + 2;
u =o + 1;
}
Wilhelm M. schrieb:> if (output_mv < 400) u = (o = (output_mv / 100) * 2 + 2) + 1;
Stimmt. Die Aufgabe war ja nicht nur Zeilen zu sparen, sondern auch
unleserlich zu schreiben.
Wilhelm M. schrieb:> z.B. auf AVR wesentlich größeren Code als:
Ist überhaupt kein Wunder, wenn Du ihm mit "volatile" die Fußfesseln
anlegst. Er muß dann für jeden Vergleich und sei er noch so überflüssig,
die Variable neu vom RAM einlesen. Optimieren ist da absolut verboten.
Schreib es als Funktion um, mit Argument und Returnwert.
Peter D. schrieb:> Wilhelm M. schrieb:>> z.B. auf AVR wesentlich größeren Code als:>> Ist überhaupt kein Wunder, wenn Du ihm mit "volatile" die Fußfesseln> anlegst. Er muß dann für jeden Vergleich und sei er noch so überflüssig,> die Variable neu vom RAM einlesen. Optimieren ist da absolut verboten.> Schreib es als Funktion um, mit Argument und Returnwert.
Lies die vorherigen Beiträge: hatte ich oben schon beschrieben
(allerdings eben nicht als Funktion in C, denn das hatte der TO auch
nicht. Zu den Problemen der geposteten Funktion mit Array der
Intervallgrenzen hatte ich auch schon etwas geschrieben).
Mark W. schrieb:> Ging mir hier um die Uebersichtlichkeit
Das passt aber nicht zu deiner eigenen Aufgabe:
Re: Code unleserlich schreiben um Zeilen zu sparen.
Erwin D. schrieb:> Mark W. schrieb:>> Ging mir hier um die Uebersichtlichkeit>> Das passt aber nicht zu deiner eigenen Aufgabe:> Re: Code unleserlich schreiben um Zeilen zu sparen.
Ja, ich gebe zu die Ueberschrift war etwas falsch ausgedrueckt.
Statt "unleserlich" koennte ich auch "abweichend von der Norm"
geschrieben haben. Das traefe es dann besser.
Aber der Post hat sich fuer mich gelohnt, ich habe viele verschiedene
Sreibweisen fuer eine Aufgabe gesehen.
Danke nochmal an alle Beteiligten.
Code "kurz" und "unleserlich" schreiben muss nicht immer paarweise
auftreten. Oftmals fällt eine Codepassage in sich zusammen, wenn man
sich mal Gedanken macht, und wird gleichzeitig einfacher verständlich.
Leider wird Code oftmals nur "hingerotzt"...
Mark W. schrieb:> Ja, ich gebe zu die Ueberschrift war etwas falsch ausgedrueckt.> Statt "unleserlich" koennte ich auch "abweichend von der Norm"
Wollte ich auch gerade schreiben. Und ja, der Code wird (bei
vorausgesetzter, geeigneter IDE) leserlicher, wenn das komplette if im
Blocksatz in eine Zeile gequetscht wird. Nur dann kann man überhaupt mit
dem Auge erkennen, ob
- eine Systematik besteht
- die Änderungen der Werte gleichen Mustern folgen
- Schreibfehler dazwischen gerutscht sind (z.B. u und o bei einem if
vertauscht)
- welche (der hier vorgestellten) Optimierungen möglich/nötig/sinnvoll
sind.
Da wir Code sowieso nur für uns (und nicht für den Compiler) schreiben,
sollte eine Optimierung (zu einer Formel) auch nur erfolgen, wenn es
dadurch noch besser lesbar wird! (Abgesehen von den ganz wenigen Fällen,
in denen Speicher- oder Zeit-Optimierung notwendig ist)
g457 schrieb:> Wie schon geschurbt wurde ist das non-standard. Würde hierzufirma wohl> auch (berechtigterweise) zum Rauswurf führen.
Höhöhö, die rauswerfen dürfen, haben meistens nicht das notwendige
Fachwissen.
Achim S. schrieb:> Da wir Code sowieso nur für uns (und nicht für den Compiler) schreiben,> sollte eine Optimierung (zu einer Formel) auch nur erfolgen, wenn es> dadurch noch besser lesbar wird!
Wenn eine Systematik besteht, ist mir eine Formel allemal lieber als
eine lange Reihe von 'if's oder 'case's. Nicht nur aus
Optimierungsgründen, sondern auch von der Verständlichkeit her. Muss ich
sonst ja erst alles durchlesen, um zu erkennen, ob die Systematik
durchgehend ist.
Außerdem widerspricht es dem Prinzip "Don't repeat yourself", was sich
auch auf die Wartbarkeit auswirkt.
Wenn die Werte keine Systematik haben, aber ein Raster (hier 100) würde
ich ein Array nehmen und die Werte in die Deklaration schreiben.
o = arr[ output_mv /100];
u = o + 1;
Jobst Q. schrieb:> Wenn die Werte keine Systematik haben, aber ein Raster (hier 100) würde> ich ein Array nehmen und die Werte in die Deklaration schreiben.>> o = arr[ output_mv /100];> u = o + 1;
Das ist doch genau der oben beschrieben LUT Ansatz: Du hast eine
Wertemenge, die bestimmt die Anzahl der Einträge in der Tabelle, und Du
eine Abbildung des Definitionsbereiches auf die Indizes der Tabelle.
Die spannende Frage ist, wie kommt man auf die Eingangsabbildung und wie
füllt man die Tabelle, und welche Datentypen sind sinnvoll. Das macht
der generische Code, den ich oben mal gepostet hatte.
Wilhelm M. schrieb:> volatile uint8_t result;> volatile uint8_t value = 100;>> constexpr auto limits = std::make_array<uint8_t>(0, 10, 20, 40, 80,> 160);> constexpr auto intervals = make_intervals<RightOpen, Adjacent>(limits);>> int main() {> auto index = lookup(value, intervals);> if (index) {> result = *index;> }> }
Ich krieg da nur Fehler:
1
test.cpp:6: error: expected constructor, destructor, or type conversion before 'auto'
2
test.cpp:7: error: expected constructor, destructor, or type conversion before 'auto'
3
test.cpp: In function 'int main()':
4
test.cpp:10: error: ISO C++ forbids declaration of 'index' with no type
5
test.cpp:10: error: 'intervals' was not declared in this scope
6
test.cpp:10: error: 'lookup' was not declared in this scope
7
test.cpp:12: error: invalid type argument of 'unary *'
Oliver S. schrieb:> Das Ergebnis von gcc -v wäre wohl eher interessant.
ja, wobei heutzutage eher das Flag -std=...
> Wobei dem Quelltext wohl schon das ein- oder andere headerfile fehlt.
Worauf ich damit hinweisen wollte ;-)
Wilhelm M. schrieb:> constexpr auto limits = std::make_array<uint8_t>(0, 10, 20, 40, 80, 160);> constexpr auto intervals = make_intervals<RightOpen, Adjacent>(limits);
Mir gefiele diese Lösung prinzipiell ganz gut, wenn ich wüsste, was ich
für make_intervals includen muss? Auch make_array ist nicht
Standard, aber immerhin in experimental/array bzw.im Namespace
std::experimental enthalten. make_intervals hingegen kann ich weder in
der (experimentellen) Standardbibliothek noch in den Boost-Bibliotheken
finden.
Wilhelm ist vermutlich mit einem pre-Alpha gcc 10 unterwegs, und nutzt
C++27. PeDa kommt mit seinem erprobten 3er gcc, und alle anderen hängen
irgendwo dazwischen.
Da kommt es schon mal zu Unverständlichkeiten ;)
Oliver
Yalu X. schrieb:> Mir gefiele diese Lösung prinzipiell ganz gut, wenn ich wüsste, was ich> für make_intervals includen muss? Auch make_array ist nicht> Standard, aber immerhin in experimental/array bzw.im Namespace> std::experimental enthalten. make_intervals hingegen kann ich weder in> der (experimentellen) Standardbibliothek noch in den Boost-Bibliotheken> finden.
Oh, das hört sich jetzt so ein bisschen Arduino-like an: ich kann die
lib nicht finden...
Oliver S. schrieb:> Wilhelm ist vermutlich mit einem pre-Alpha gcc 10 unterwegs, und nutzt> C++27.
Mmh, C++27 wird es wohl nicht geben.
>PeDa kommt mit seinem erprobten 3er gcc, und alle anderen hängen> irgendwo dazwischen.>> Da kommt es schon mal zu Unverständlichkeiten ;)
Ok, dann versuche ich das mal aufzuklären. Ich poste einfach mal den
ganzen Code. Allerdings auch dann wird es wohl nicht klappen, ihr
braucht nämlich ein constexpr sort<>() (hier: Util::sort<>()), das
std::sort<>() ist nicht constexpr. Das es zur Compilezeit verwendet
wird, tut es ein Bubblesort ;-) (das zu schreiben überlasse ich gerade
Euch).
Alles andere ist schnell heruntergetippt, ein paar Fälle habe ich auch
ausgelassen, manche Namen sind nicht gut. Man könnte es schöner machen.
Es soll ja nur das Prinzip zeigen...
Allerdings sollte man m.E. auch eine andere Variante realisieren, die
nur mit elementar-konstanten Grenzen arbeitet. Denn diese hier kann ja
auch mit non-constexpr arbeiten.
*Thema verfehlt!*
Die Aufgabe hiess, Code unleserlich schreiben, um Zeilen zu sparen!
Ernsthaft: es ist beeindruckend, was mit modernem C++ alles geht. Aber
glaubst Du wirklich, dass das die µC-Programmierung - in Zeiten, wo der
Durchschnittsprogrammierer kaum eine Arduino-loop() fehlerfrei hinkriegt
- voranbringt?
Markus F. schrieb:> *Thema verfehlt!*
Prinzip nicht verstanden!
> Die Aufgabe hiess, Code unleserlich schreiben, um Zeilen zu sparen!
Es sind im Code des Klienten (!) 3 Zeilen. Und das bei beliebig vielen
Intervallen, die geschlossen/halboffen sein können und benachbart oder
nicht, und auch noch für beliebige Datentypen.
> Ernsthaft: es ist beeindruckend, was mit modernem C++ alles geht. Aber> glaubst Du wirklich, dass das die µC-Programmierung - in Zeiten, wo der> Durchschnittsprogrammierer kaum eine Arduino-loop() fehlerfrei hinkriegt> - voranbringt?
Ja, davon bin ich überzeugt.
Wilhelm M. schrieb:> Markus F. schrieb:>> Ernsthaft: es ist beeindruckend, was mit modernem C++ alles geht. Aber>> glaubst Du wirklich, dass das die µC-Programmierung - in Zeiten, wo der>> Durchschnittsprogrammierer kaum eine Arduino-loop() fehlerfrei hinkriegt>> - voranbringt?>> Ja, davon bin ich überzeugt.
Vielleicht wäre es gut in den Beispielen die C++-Version und die
Minimum-Compilerversion anzugeben. Im obigen Fall C++14/gcc4.9. Es gibt
ja auch noch Leute, die Winavr2010(gcc4.3 oder so) benutzen, das
behindert diese dann beim Mitüberzeigtsein.
Wobei gcc7.3 komplett C++17 kann, man also nicht wirklich Angst vor
Alpha-Versionen haben muß, wenn man ganz up TO Date sein will,
z.B. mit "if constexpr"
Wilhelm M. schrieb:> Mmh, C++27 wird es wohl nicht geben.
Das war schon so gemeint, wie es da steht. 20, 23, 26, dazu auf dem Weg
dahin ein Jahr Verspätung, das passt schon.
Oliver
Wilhelm M. schrieb:> Yalu X. schrieb:>> Mir gefiele diese Lösung prinzipiell ganz gut, wenn ich wüsste, was ich>> für make_intervals includen muss? Auch make_array ist nicht>> Standard, aber immerhin in experimental/array bzw.im Namespace>> std::experimental enthalten. make_intervals hingegen kann ich weder in>> der (experimentellen) Standardbibliothek noch in den Boost-Bibliotheken>> finden.>> Oh, das hört sich jetzt so ein bisschen Arduino-like an: ich kann die> lib nicht finden...
Naja, ich dachte, ich hätte da vielleicht irgendein neues C++17- oder
C++20-Feature verpasst, was aber offensichtlich nicht der Fall ist, da
du make_intervals und lookup selber geschrieben hast.
Damit hat aber deine Lösung in meinen Augen ganz gewaltig an Eleganz
verloren. Natürlich kann man jedes noch so komplexe Problem mit einem
Ein- oder Zweizeiler lösen, wenn diese Zeilen aus Aufrufen von
Funktionen bestehen, die erst noch entwickelt werden müssen. Im
konkreten Fall hast du ein Problem, das man auf klassische Weise in 1
bis 10 Codezeilen (je nachdem, ob die Schwellwerte äquidistant sind oder
nicht) umsetzen würde, durch ein Konstrukt gelöst, das zugegebenermaßen
ganz pfiffig ist, dafür aber 70 Codezeilen umfasst und dabei noch nicht
einmal Dinge wie die Optimierungsmöglichkeit im Fall von äquidistanten
Schwellwerten nutzt.
Wenn man bedenkt, dass der zusätzliche Code auch getestet, gedebugt und
dokumentiert werden muss und dass man diese Intervallsuche nur relativ
selten benötigt, hat man mit deiner Lösung außer Erkenntnisgewinn nichts
gewonnen und stattdessen zusätzlichen Entwicklungsaufwand verursacht.
Ganz anders läge der Fall, wenn die Funktionen make_interval und
lookup durch die Standardbibliothek bereitgestellt würden. Dann würde
der Aufwand für Implementierung, Test, Debugging und Dokumentation
weitgehend entfallen, so dass die Lösung fast jeder selbstgeschriebenen
Variante vorzuziehen wäre.
Das ist auch der Grund, warum ich nachgefragt habe. Obwohl ich deine
negative Antwort eigentlich schon erwartet habe, bin ich jetzt doch ein
ganz klein wenig enttäuscht :)
PS:
Wilhelm, mal Hand aufs Herz: Glaubst du, der TE hätte es von sich aus
wirklich geschafft, nach dem Lesen deines Beitrags vom 02.06.2018
09:44 die Funktionen make_intervals und lookup selber zu schreiben?
Mark W. schrieb:> Naja, zum Glueck bin ich ja kein Software-Entwickler.
PPS:
Wilhelm M. schrieb:> a) benutze Algorithmen / Funktionen, keine expl. IterationenWilhelm M. schrieb:> for(typename Limits::size_type n = 0; n < in.size(); ++n) {> ...> for(typename Limits::size_type n = 0; n < in.size(); ++n) {> ...> for(typename Limits::size_type n = 0; n < in.size(); ++n) {> ...Wilhelm M. schrieb:> b) benutze Algorithmen / Funktionen, keine expl. AlternativenWilhelm M. schrieb:> if constexpr(std::is_same_v<Type, RightOpen>) {> ...> if constexpr(std::is_same_v<Type, RightOpen>) {> ...> if constexpr(!std::is_same_v<Construct, Adjacent>) {> ...> if (intervals[n].includes(value)) {> ...
Yalu X. schrieb:> Wilhelm M. schrieb:>> b) benutze Algorithmen / Funktionen, keine expl. Alternativen>> Wilhelm M. schrieb:>> if constexpr(std::is_same_v<Type, RightOpen>) {>> ...>> if constexpr(std::is_same_v<Type, RightOpen>) {>> ...>> if constexpr(!std::is_same_v<Construct, Adjacent>) {>> ...>> if (intervals[n].includes(value)) {>> ...
"if constexpr" ist nicht so leicht durch anderes ersetzbar (außer
kompliziertem Template-Zeugs)
BTW, das hatte ich beim Überfliegen gar nicht bemerkt, also IST das
C++-17.
Mark W. schrieb:> schreibt Ihr auch gelegentlich mal Code, nur um Zeilen zu sparen?> Oder geht das gar nicht?> if(output_mV < 100){o = 4; u = 5;}
Ich mag soetwas garnicht. Bei mir (in VBA) bekommt jede Variable eine
eigene Deklarationszeile und einen sprechenden Namen. Damit ich immer
weiss welche Variable was macht.
Mark W. schrieb:> Ging mir hier um die Uebersichtlichkeit, weil man da beim Schreiben> weniger scrollen muss.
Übersichtlichkeit erreicht man durch Einrücken. Oder durch Auslagern von
Codeteilen in Rückgabefunktionen. Zumindest in VBA ist es einfach. Wenn
ich eine umfangreiche Userform erstellen muss lagere ich die Prozeduren
in Module aus. Jede Prozedur in ein eigenes Modul. Das Modul bekommt den
Namen der Prozedur, wobei ein "mdl" davorgesetzt wird (Modul und
Prozedur dürfen nicht den selben Namen tragen, sonst kommt es zu
Konflikten). Die Callbacks im Userform-Codemodul rufen dann nur die
Prozeduren auf und sind somit einzeilig. Ergebnis ist eine gute
Übersichtlichkeit die ich auch noch nach Jahren problemlos
nachvollziehen kann, und scrollen muss ich dann auch nicht mehr (es sei
denn der Code ist etwas länger).
René H. schrieb:> Oder durch Auslagern von> Codeteilen in Rückgabefunktionen
Das gilt nicht "absolut". Ganz grob, bei einem Anfänger-Projekt von 1000
Zeilen sind ~10 Files je ~10 Funktionen je ~10 Zeilen vielleicht
übersichtlich. Bei 1E5 Codezeilen würde man die 30 Zeilen des TO NICHT
auslagern (wenn sie nur einmal gebraucht werden). Dann sind auch
Funktionen mit 100 oder 1000 Zeilen normal und Tabellen (Blocksatz) ein
Mittel der Wahl.
Achim S. schrieb:> Dann sind auch Funktionen mit 100 oder 1000 Zeilen normal und Tabellen> (Blocksatz) ein Mittel der Wahl.
Das ist eher Spaghetti Code. Gerade bei großen Projekten sollten
Funktionen nicht so lang werden. Besser ist es, viele kleine Funktionen
(ca 10 Zeilen) zu haben, die genau einen Aspekt bearbeiten und alles
andere ggf. delegieren. So werden sie viel leichter verständlich. Diese
typischen Riesen-Algorithmen in Anfänger-Code lassen sich meist in viele
kleine Einheiten aufteilen. Die kann man dann auch wieder verwenden.
Große Tabellen sollten auch eher die Ausnahme sein. Oft lassen die sich
auch automatisch per constexpr generieren.
Carl D. schrieb:> Wilhelm M. schrieb:>> Markus F. schrieb:>>> Ernsthaft: es ist beeindruckend, was mit modernem C++ alles geht. Aber>>> glaubst Du wirklich, dass das die µC-Programmierung - in Zeiten, wo der>>> Durchschnittsprogrammierer kaum eine Arduino-loop() fehlerfrei hinkriegt>>> - voranbringt?>>>> Ja, davon bin ich überzeugt.>> Vielleicht wäre es gut in den Beispielen die C++-Version und die> Minimum-Compilerversion anzugeben.
Ja, sicher: ab C++17, also -std=c++17 oder -std=c++2a
> Im obigen Fall C++14/gcc4.9. Es gibt> ja auch noch Leute, die Winavr2010(gcc4.3 oder so) benutzen, das> behindert diese dann beim Mitüberzeigtsein.AVR wird eher schwierig, da es keine libstdc++ offiziell für die
8-Bitter gibt. Ich habe meine eigene Realisierung, die bestimmte
Optimierungen bzgl. der intern verwendeten DT macht.
> Wobei gcc7.3 komplett C++17 kann, man also nicht wirklich Angst vor> Alpha-Versionen haben muß, wenn man ganz up TO Date sein will,> z.B. mit "if constexpr"
Oh, seit 02.05.18 haben wir auch 8.1 released, der kann auch
familiar-template-syntax für generische lambdas. Das finde ich sehr
schön.
Oliver S. schrieb:> Wilhelm M. schrieb:>> Mmh, C++27 wird es wohl nicht geben.>> Das war schon so gemeint, wie es da steht. 20, 23, 26, dazu auf dem Weg> dahin ein Jahr Verspätung, das passt schon.
Der Standard wird sich nicht verspäten, das wird C++26. Allerdings
werden wohl einige Compiler wieder notorisch hinter hinken.
Yalu X. schrieb:> Wilhelm M. schrieb:>> Yalu X. schrieb:>>> Mir gefiele diese Lösung prinzipiell ganz gut, wenn ich wüsste, was ich>>> für make_intervals includen muss? Auch make_array ist nicht>>> Standard, aber immerhin in experimental/array bzw.im Namespace>>> std::experimental enthalten. make_intervals hingegen kann ich weder in>>> der (experimentellen) Standardbibliothek noch in den Boost-Bibliotheken>>> finden.>>>> Oh, das hört sich jetzt so ein bisschen Arduino-like an: ich kann die>> lib nicht finden...>> Naja, ich dachte, ich hätte da vielleicht irgendein neues C++17- oder> C++20-Feature verpasst, was aber offensichtlich nicht der Fall ist, da> du make_intervals und lookup selber geschrieben hast.>> Damit hat aber deine Lösung in meinen Augen ganz gewaltig an Eleganz> verloren. Natürlich kann man jedes noch so komplexe Problem mit einem> Ein- oder Zweizeiler lösen, wenn diese Zeilen aus Aufrufen von> Funktionen bestehen, die erst noch entwickelt werden müssen.
Ja, das sollte man auch tun. Dann seine Testfälle dafür schreiben und
diese Funktion in seinen Werkzeugkasten legen.
> Im> konkreten Fall hast du ein Problem, das man auf klassische Weise in 1> bis 10 Codezeilen (je nachdem, ob die Schwellwerte äquidistant sind oder> nicht) umsetzen würde, durch ein Konstrukt gelöst, das zugegebenermaßen> ganz pfiffig ist, dafür aber 70 Codezeilen umfasst
Dafür kann dieses Konstrukt eben auch mit allen Intervallarten und allen
Datentypen umgehen. Das ist schon ein wesentlicher Unterschied.
> und dabei noch nicht> einmal Dinge wie die Optimierungsmöglichkeit im Fall von äquidistanten> Schwellwerten nutzt.
Aus das wäre kein Problem, statt Intervalle anzugeben, eine
Abbildungsfunktion anzugeben. (BTW: wobei man bei der Indizierung eines
rohen Arrays zumindest mal Assertionen über die Indizes einbauen sollte,
und nicht wie es oben schon mal gepostet wurde.)
> Wenn man bedenkt, dass der zusätzliche Code auch getestet, gedebugt und> dokumentiert werden muss
Das ist kein Argument, denn Dein Code muss auch getestet, korrigiert und
dokumentiert werden. Allerdings mache ich das in meiner Bibliothek
einmal und Du in jeder Anwendung immer wieder.
> und dass man diese Intervallsuche nur relativ> selten benötigt, hat man mit deiner Lösung außer Erkenntnisgewinn nichts> gewonnen und stattdessen zusätzlichen Entwicklungsaufwand verursacht.
Das ist eine Milchmädchenrechnung: um Copy-n-Paste Lösungen vorzubeugen,
sollte man versuchen, so viel wie möglich zu generalisieren und aus
Bibliotheken zu entnehmen bzw. eben den eigenen Bibliotheken
hinzuzufügen. Der Aufwand hat sich im Gesamten schnell wieder
amortisiert.
> Ganz anders läge der Fall, wenn die Funktionen make_interval und> lookup durch die Standardbibliothek bereitgestellt würden. Dann würde> der Aufwand für Implementierung, Test, Debugging und Dokumentation> weitgehend entfallen, so dass die Lösung fast jeder selbstgeschriebenen> Variante vorzuziehen wäre.
Ja, aber die libstdc++ ist nicht allumfassend und wird es auch nie sein.
Vielleicht gibt es auf dieser Welt eine andere vertrauensvolle
Bibliothek, die das realisiert - ich habe nicht danach gesucht.
Aber: schreibst Du keine Bibliotheken für Deine Projekte bzw.
Anwendungsdomäne?
> Das ist auch der Grund, warum ich nachgefragt habe. Obwohl ich deine> negative Antwort eigentlich schon erwartet habe, bin ich jetzt doch ein> ganz klein wenig enttäuscht :)
Du bist enttäuscht, dass die libstdc++ dafür keine mundgerechte Lösung
parat hat? Man könnte es mit adjacent_find<>() machen ... allerdings ist
das nicht constexpr, was ja hier hilfreich wäre.
> PS:>> Wilhelm, mal Hand aufs Herz: Glaubst du, der TE hätte es von sich aus> wirklich geschafft, nach dem Lesen deines Beitrags vom 02.06.2018> 09:44 die Funktionen make_intervals und lookup selber zu schreiben?
Das kann und will ich nicht beurteilen. Aber es könnte sein, das der TE
und einige andere etwas an Erkenntnis aus dieser Diskussion mitnimmt.
Und sei es auch nur, neugierig auf Neues zu sein.
> PPS:>> Wilhelm M. schrieb:>> a) benutze Algorithmen / Funktionen, keine expl. Iterationen>> Wilhelm M. schrieb:>> for(typename Limits::size_type n = 0; n < in.size(); ++n) {>> ...>> for(typename Limits::size_type n = 0; n < in.size(); ++n) {>> ...>> for(typename Limits::size_type n = 0; n < in.size(); ++n) {>> ...
Dies bezieht sich immer auf den Code der Klienten. Wie meinst Du denn,
ist z.B. ein std::copy<>() implementiert?
Es ist wichtig, die Grenze zwischen Code des Klienten und den
Bibliotheken zu beachten. Im obigen Beispiel war es eigentlich klar.
Also nochmal: das meiste ist bibliotheksbezogen, nur make_array,
make_intervals und lookup ist für den Klienten.
> Wilhelm M. schrieb:>> b) benutze Algorithmen / Funktionen, keine expl. Alternativen>> Wilhelm M. schrieb:>> if constexpr(std::is_same_v<Type, RightOpen>) {>> ...>> if constexpr(std::is_same_v<Type, RightOpen>) {>> ...>> if constexpr(!std::is_same_v<Construct, Adjacent>) {>> ...>> if (intervals[n].includes(value)) {>> ...
Auch hier gilt natürlich das oben Gesagte: auch ein std::find<>() wird
nicht ohne eine Laufzeit-Alternative auskommen. Hier ist es allerdings
kein Laufzeit-if, sondern eine bedingte template-Instanziierung (bis auf
das letzte zitierte if).
Wilhelm M. schrieb:> Ja, sicher: ab C++17, also -std=c++17 oder -std=c++2a>>> Im obigen Fall C++14/gcc4.9. Es gibt>> ja auch noch Leute, die Winavr2010(gcc4.3 oder so) benutzen, das>> behindert diese dann beim Mitüberzeigtsein.>> AVR wird eher schwierig, da es keine libstdc++ offiziell für die> 8-Bitter gibt. Ich habe meine eigene Realisierung, die bestimmte> Optimierungen bzgl. der intern verwendeten DT macht.
Kenn ich ;-) Macht es schwierig die oft verlangten Beispiele zu liefern,
ohne gleich ein dickes Zip-File dazupacken zu müssen. Ich hab mir bisher
immer Dinge, die mir gefehlt haben, entweder aus dem Original geliehen,
oder wenn's Triviales war, einfach selber geschrieben.
> Oh, seit 02.05.18 haben wir auch 8.1 released, der kann auch> familiar-template-syntax für generische lambdas. Das finde ich sehr> schön.
Dann wird's noch schwieriger, denn dann wollen/müssen die ja auch noch
den "Selbstbau"-Compiler dazu haben.
Es ging ja darum, den Code "unleserlich" zu schreiben ;-)
Deswegen habe ich gerade nochmal eine Variante erstellt, die
ausschließlich statisch arbeitet, d.h. sie ist das direkte Äquivalent zu
hardcoded if-stmts. Allerdings immer noch mit dem Vorteil der
unterschiedlichen Intervallarten und Datentypen.
Strengt Euch nicht an, das bei Euch zum Compilieren zu bekommen: es
fehlt Euch die Meta-Programm-Bibliothek im namespace Meta. Aber
vielleicht kann man trotzdem erkennen, was gemacht wird. Na ja, das
Wesentliche ist eigentlich die zentrale fold-expression.
Carl D. schrieb:>> Oh, seit 02.05.18 haben wir auch 8.1 released, der kann auch>> familiar-template-syntax für generische lambdas. Das finde ich sehr>> schön.> Dann wird's noch schwieriger, denn dann wollen/müssen die ja auch noch> den "Selbstbau"-Compiler dazu haben.
Im aktuellen MinGW ist doch aber auch der offizielle gcc 8.1 drin.
Wilhelm M. schrieb:> Ich poste einfach mal den ganzen Code.
Na das ist ja ne ganze Menge Holz, was da zusätzlich benötigt wird.
Ich denke nicht, daß es sich lohnt, immer sofort ne Lib zu schreiben,
die Aufgaben sind zu vielfältig.
Hier noch ein kleines praktisches Beispiel in plain C aus meiner
Tastenabfrage mit ADC. Die Suchtabelle ist nichtlinear und wird mit dem
Ohmschen Gesetz berechnet. Es wird die Bitstelle der gedrückten Taste
ermittelt.
Wilhelm M. schrieb:> Aber: schreibst Du keine Bibliotheken für Deine Projekte bzw.> Anwendungsdomäne?
Doch, nur ich habe mir (aus gutem Grund) abgewöhnt, Funktionen oder
Klassen mit Zusatzfeatures zu schreiben, deren spätere Verwendung
ungewiss ist. Anders ausgedrückt, produziere ich keinen Code "auf
Halde". In deinem Beispiel wäre die Option Disjoint so ein Fall. Da
mir dafür kein konkretes Anwendungsbeispiel einfällt, würde ich das
Feature auch nicht implementieren.
Wilhelm M. schrieb:> Du bist enttäuscht, dass die libstdc++ dafür keine mundgerechte Lösung> parat hat? Man könnte es mit adjacent_find<>() machenadjacent_find passt wohl nicht so richtig für das Problem des TE, aber
was spricht gegen find_if? Für die Zukunft schöner fände ich find_if
aus experimental/ranges/algorithm, da man dort das Array mit den
Schwellwerten direkt (ohne den hässlichen Umweg über den first- und
last-Iterator) übergeben kann.
> ... allerdings ist das nicht constexpr, was ja hier hilfreich wäre.
Das empfinde ich nicht als Nachteil, das der zu untersuchende Wert (beim
TE output_mV) i.Allg. sowieso variabel ist.
Wilhelm M. schrieb:>> Wilhelm M. schrieb:>>> a) benutze Algorithmen / Funktionen, keine expl. Iterationen>>>> Wilhelm M. schrieb:>>> for(typename Limits::size_type n = 0; n < in.size(); ++n) {>>> ...>>> for(typename Limits::size_type n = 0; n < in.size(); ++n) {>>> ...>>> for(typename Limits::size_type n = 0; n < in.size(); ++n) {>>> ...>> Dies bezieht sich immer auf den Code der Klienten. Wie meinst Du denn,> ist z.B. ein std::copy<>() implementiert?
Für mich ist eine Iteration nur dann implizit, wenn ich sie nicht selber
geschrieben habe. Aus der Sicht des TE, der deinen Code benutzt, sind
die Iterationen tatsächlich implizit. Als du dieses schriebst:
Wilhelm M. schrieb:> a) benutze Algorithmen / Funktionen, keine expl. Iterationen
hatte der TE aber noch gar keinen Zugriff auf deinen Code, weswegen er
die Funktionen selber implementieren hätte müssen. Damit wären die
Iterationen für ihn explizit, denn alleine das Verlagern einer Iteration
in einen anderen Code-Abschnitt macht diese noch lange nicht implizit.
Wilhelm M. schrieb:> Strengt Euch nicht an, das bei Euch zum Compilieren zu bekommen:
Das war auch nur der Versuch, anhand des Assemblerlistings
herauszufinden, was Dein Programm eigentlich macht. Beim Lesen der
Sourcen erschließen sich mir nur wenige Teilaspekte, aber nicht der
eigentliche Ablauf.
Peter D. schrieb:> Hier noch ein kleines praktisches Beispiel in plain C aus meiner> Tastenabfrage mit ADC. Die Suchtabelle ist nichtlinear und wird mit dem> Ohmschen Gesetz berechnet. Es wird die Bitstelle der gedrückten Taste> ermittelt.
Ich habe Deinen Code mal ergänzt zu:
Wie Du siehst, habe ich einmal genau Deinen Code mit der Taste als
Bit-Muster und einmal eine günstigere Variante mit der Taste als Nummer
erstellt.
Hier die Zahlen jeweils bezogen auf AVR m328:
Meine Variante : 192 flash, 2 data
Deine Variante i : 210 flash, 2 data
Deine Variante ii: 214 flash, 2 data
Bei mir erstellt Converter<> mit Hilfe des Generator ein
PgmArray<Boundary<uint8_t, RightOpen>>. Wie der Name schon sagt, liegen
die Daten des PgmArray im ProgMem des AVR.
Yalu X. schrieb:> Wilhelm M. schrieb:>> Du bist enttäuscht, dass die libstdc++ dafür keine mundgerechte Lösung>> parat hat? Man könnte es mit adjacent_find<>() machen>> adjacent_find passt wohl nicht so richtig für das Problem des TE,
Passt genau, wenn man unzusammenhängende Intervalle hat (Option
Disjoint). Falls man in dem Beispiel von Peter D. noch eine Hysterese
einbauen wollte.
> aber> was spricht gegen find_if?
Passt nur für zusammenhängende Intervalle.
> Für die Zukunft schöner fände ich /find_if/> aus experimental/ranges/algorithm, da man dort das Array mit den> Schwellwerten direkt (ohne den hässlichen Umweg über den first- und> last-Iterator) übergeben kann.
Das ist ein Einzeiler wenn es nur um die Iteratoren geht.
>> ... allerdings ist das nicht constexpr, was ja hier hilfreich wäre.>> Das empfinde ich nicht als Nachteil, das der zu untersuchende Wert (beim> TE output_mV) i.Allg. sowieso variabel ist.
constexpr schränkt das ja auch nicht ein, es bietet eben nur die
Möglichkeit in einem constexpr-Kontext.
> Für mich ist eine Iteration nur dann implizit, wenn ich sie nicht selber> geschrieben habe. Aus der Sicht des TE, der deinen Code benutzt, sind> die Iterationen tatsächlich implizit. Als du dieses schriebst:>> Wilhelm M. schrieb:>> a) benutze Algorithmen / Funktionen, keine expl. Iterationen>> hatte der TE aber noch gar keinen Zugriff auf deinen Code, weswegen er> die Funktionen selber implementieren hätte müssen. Damit wären die> Iterationen für ihn explizit, denn alleine das Verlagern einer Iteration> in einen anderen Code-Abschnitt macht diese noch lange nicht implizit.
Jein. Wenn er es wie gesagt in eine (eigene) Bibliothek mit
entsprechenden Tests, etc. auslagern würde, dann wäre es auch dort
implizit. Du kannst auch Klient Deines eigenen Codes sein. Das passiert
ja manchmal auch auf Umwegen.
Wilhelm M. schrieb:> Bei mir erstellt Converter<> mit Hilfe des Generator ein ...
???
Ich hab nicht die geringste Idee, welche Zeile das Array definiert und
wo die Schleife mit dem Vergleich auf "<" ist.
Und da ich es ja eh nichtmal compiliert werden kriege, bleibe ich wohl
besser bei plain C.
Ich nehme mal an, zum Compilieren ist noch ne riesen Latte von Deinen
speziellen Headern nötig, die Du leider nicht angegeben hast.
Mein Code war vollständig, d.h. er compiliert ohne weitere Header.
An plain C mag ich, daß es gut dokumentiert ist, z.B. wenn ich nach
scanf, printf usw. google.
Suche ich dagegen nach Converter, Generator, RightOpen usw., kann mir
Google nicht helfen. Das macht es natürlich schwer, solche
Schlüsselwörter zu benutzen.
Peter D. schrieb:> Suche ich dagegen nach Converter, Generator, RightOpen usw., kann mir> Google nicht helfen. Das macht es natürlich schwer, solche> Schlüsselwörter zu benutzen.
Das sind auch keine Schlüsselworte, sondern selbstgeschriebene
Funktionen. Da kann dir Google wirklich nicht weiterhelfen.
Oliver
Hier ist eine Variante von Peters Code die mittels Metaprogrammierung
das Array berechnet. Der Hauptvorteil besteht hier darin, dass man durch
eine einzige Zahl die Anzahl der Einträge bestimmen kann, und man die
genLUT-Funktion auch problemlos für beliebige andere LUT's recyclen
kann. Eleganter wär's noch die Zahlen nicht als globale Konstanten zu
übergeben sondern z.B. als template-Parameter an treshold; das sei als
Übung dem Leser überlassen :)
Der Code ist vollständig und mit C++14 kompilierbar. Selbstverständlich
ist auch C++ dokumentiert (nicht nur im Standard), und alle Dinge die
hier nicht im Code definiert sind kann man Googlen:
1
#include<iostream>
2
#include<utility>
3
#include<array>
4
#include<cstddef>
5
#include<cstdint>
6
7
staticconstexprdoubleRVCC=10.0;// 10k to VCC
8
staticconstexprdoubleRROW=1.0;// 1k between rows
9
staticconstexprdoubleRCOL=3.9;// 3k9 between colums
10
staticconstexprstd::size_tNROW=4;// number of rows
Die 0 am Ende des Arrays hab ich weggelassen; ich finde es eleganter per
THRESHOLDS.size() die Größe explizit abzufragen, so stören auch
gewünschte Nullen im Array nicht.
Oliver S. schrieb:> Das sind auch keine Schlüsselworte, sondern selbstgeschriebene> Funktionen.
Das hatte ich mir schon gedacht. Dann sind aber Codebeispiele ohne die
benötigten Funktionsdefinitionen ziemlich sinnlos. Beispiele sollten
schon nachvollziehbar sein.
Dr. Sommer schrieb:> Das ist eher Spaghetti Code. Gerade bei großen Projekten sollten> Funktionen nicht so lang werden. Besser ist es, viele kleine Funktionen> (ca 10 Zeilen) zu haben, die genau einen Aspekt bearbeiten und alles> andere ggf. delegieren.
Wenn 1E6-Zeilen in 100 Treiber zu je 1E4 Zeilen zerfallen, hast Du
recht. Ich vermute, du redest von so was.
> Diese typischen Riesen-Algorithmen in Anfänger-Code lassen sich meist> in viele kleine Einheiten aufteilen.
Auch das stimmt. Davon ist bei mir aber nicht die Rede.
> Die kann man dann auch wieder verwenden.
Auch das stimmt. Aber was soll das?
Das man eine Aufgabe auf verschiedene Arten beleuchten soll um Synergien
und Vereinfachungen zu finden, sicher. Aber irgendwie anzunehmen, dass
komplexe Dinge (und nur um die geht es hier) einfacher werden, wenn ich
sie aus ihrem Kontext reiße und diesen mnühsam wieder herstelle (bzw.
muss), zeigt doch nur, dass Du die Straße vermutlich noch nie gegangen
bist. Also nichts für ungut.
Achim S. schrieb:> Wenn 1E6-Zeilen in 100 Treiber zu je 1E4 Zeilen zerfallen, hast Du> recht. Ich vermute, du redest von so was.
Nö, auch von monolithischen Projekten. Auch da braucht man keine
1000-Zeilen-Funktionen. Die lassen sich zu 99% in handlichere Funktionen
aufteilen. Und wenn das einen "Kontext zerreißt" sind die Daten-und
Programmstrukturen wohl nicht gut konstruiert.
Achim S. schrieb:> zeigt doch nur, dass Du die Straße vermutlich noch nie gegangen> bist. Also nichts für ungut.
Ad Hominem, ich hör dir trappsen. Ja, ich hab auch mal Spaghetti-Code
geschrieben. Vor >10 Jahren... :)
Dr. Sommer schrieb:> Hier ist eine Variante von Peters Code die mittels Metaprogrammierung> das Array berechnet. Der Hauptvorteil besteht hier darin, dass man durch> eine einzige Zahl die Anzahl der Einträge bestimmen kann, und man die> genLUT-Funktion auch problemlos für beliebige andere LUT's recyclen> kann.
Warum nicht C++17? Dann sind lambdas (automatisch) constexpr. Da geht
das alles viel einfacher.
1
#include<iostream>
2
#include<utility>
3
#include<array>
4
#include<cstddef>
5
#include<cstdint>
6
7
staticconstexprdoubleRVCC=10.0;// 10k to VCC
8
staticconstexprdoubleRROW=1.0;// 1k between rows
9
staticconstexprdoubleRCOL=3.9;// 3k9 between colums
10
staticconstexprstd::size_tNROW=4;// number of rows
Allerdings haben wir damit nur die Tabelle, noch keine Verwendung dieser
als Intervallbildner oder unterschiedliche Intervallarten (was ich oben
gepostet hatte).
Macht man dieses Beispiel etwa auch noch auf einem AVR, so landet die
Tabelle im RAM, entweder im data-segment oder auf dem Stack (als local
object). Deswegen habe ich oben mit einem PgmArray gearbeitet.
Wilhelm M. schrieb:> Warum nicht C++17? Dann sind lambdas (automatisch) constexpr. Da geht> das alles viel einfacher.
Naja, die Idee war ja schon die Funktion genLUT wiederverwendbar zu
machen... :) Und das ging in C++14 halt auch. Keil und Konsorten können
auch kein C++17...
Wilhelm M. schrieb:> Allerdings haben wir damit nur die Tabelle,
Peter's Funktion ließe sich damit direkt problemlos nutzen. Wollte sie
nur nicht kopieren.
Wilhelm M. schrieb:> Macht man dieses Beispiel etwa auch noch auf einem AVR, so landet die> Tabelle im RAM, entweder im data-segment oder auf dem Stack (als local> object). Deswegen habe ich oben mit einem PgmArray gearbeitet.
Ja, sowas braucht man da auch, aber ich kenn mich mit der ganzen
AVR-Progmem-Geschichte nicht so aus, bin zu verwöhnt von ARM :)
Oliver S. schrieb:> Peter D. schrieb:>> Suche ich dagegen nach Converter, Generator, RightOpen usw., kann mir>> Google nicht helfen. Das macht es natürlich schwer, solche>> Schlüsselwörter zu benutzen.>> Das sind auch keine Schlüsselworte, sondern selbstgeschriebene> Funktionen. Da kann dir Google wirklich nicht weiterhelfen.
Wenn ich nach key_no aus Peters Code google, finde ich auch nichts
passendes ;-)
Funktionen sind es in der Tat nicht, sondern:
Converter ist ein Klassen-Template
Generator ist eine Klasse, geschrieben als Funktor
RightOpen, LeftOpen, ... Adjacent, ... sind Klassen gebraucht aus sog.
Tag-Typen.
Dr. Sommer schrieb:> Wilhelm M. schrieb:>> Warum nicht C++17? Dann sind lambdas (automatisch) constexpr. Da geht>> das alles viel einfacher.> Naja, die Idee war ja schon die Funktion genLUT wiederverwendbar zu> machen... :) Und das ging in C++14 halt auch. Keil und Konsorten können> auch kein C++17...
Au weia, schlafen die alle?
> Wilhelm M. schrieb:>> Allerdings haben wir damit nur die Tabelle,> Peter's Funktion ließe sich damit direkt problemlos nutzen. Wollte sie> nur nicht kopieren.
Na ja, sollt eman umbauen, damit das Sentinel 0 nicht stört.
> Wilhelm M. schrieb:>> Macht man dieses Beispiel etwa auch noch auf einem AVR, so landet die>> Tabelle im RAM, entweder im data-segment oder auf dem Stack (als local>> object). Deswegen habe ich oben mit einem PgmArray gearbeitet.> Ja, sowas braucht man da auch, aber ich kenn mich mit der ganzen> AVR-Progmem-Geschichte nicht so aus, bin zu verwöhnt von ARM :)
Ich wollte es nur erwähnen, sonst gibt es gleich wieder großes Geschrei
... und wie gesagt, auch dafür gibt es eine Lösung.
Wilhelm M. schrieb:> Au weia, schlafen die alle?
Die entwickeln halt lieber "wichtige" Dinge weiter wie die
Klicki-Bunti-GUI. Im Embedded Bereich ist C++ ja eh verteufelt. Da bin
ich froh dass sie es bis C++14 geschafft haben... Selbst MSVC kann C++17
noch nicht.
Dr. Sommer schrieb:> Wilhelm M. schrieb:>> Au weia, schlafen die alle?>> Die entwickeln halt lieber "wichtige" Dinge weiter wie die> Klicki-Bunti-GUI. Im Embedded Bereich ist C++ ja eh verteufelt. Da bin> ich froh dass sie es bis C++14 geschafft haben... Selbst MSVC kann C++17> noch nicht.
Hier sieht es aber bzgl. MSCV ganz gut aus:
https://en.cppreference.com/w/cpp/compiler_support
Keil könnte sich ja das frontend von EDG kaufen - das machen einige auch
für ihre IDEs.
Bei allem Respekt vor euren c++ Kenntnissen, auf die ich schon ein
bisschen neidisch bin: was nützt es, geilen Code zu schreiben, der nur
von 10% der potentiellen Kollegen verstanden wird? Ich benutze auch
gerne einen Teil von c++, aber da ich ab und zu ein Produkt ausliefern,
weiter entwickeln oder gar warten muss, habe ich leider nicht in dem
Maße Zeit mich in neue c++e einzuarbeiten. Ich verstehe leider
vornehmlich Bahnhof.
Wilhelm M. schrieb:> Hier sieht es aber bzgl. MSCV ganz gut aus:
Aha, das ist ganz neu - jetzt auch mit fold expressions und
template-auto. Gut zu wissen, dann kann ich meinen C++17 Code damit mal
testen.
Hier steht mehr dazu:
https://blogs.msdn.microsoft.com/vcblog/2018/05/07/announcing-msvc-conforms-to-the-c-standard/Karl schrieb:> was nützt es, geilen Code zu schreiben, der nur> von 10% der potentiellen Kollegen verstanden wird?
Es gibt Kollegen die können C++. Das gleiche Problem hat man doch mit
allen Tools und Sprachen - von Assembler bis Prolog. Das ist kein
prinzipielles Problem von C++. Bei meinem AG ist C++ die Hauptsprache,
neben einer ganzen Reihe weiterer.
Wilhelm M. schrieb:> u = o = 0;> if (output_mv < 400) u = (o = (output_mv / 100) * 2 + 2) + 1;
warum nicht gleich als einzeiler!?
if (u = o = 0, output_mv < 400) u = (o = (output_mv / 100) * 2 + 2) + 1;
Mark W. schrieb:> if(output_mV > 199 && output_mV < 300)> {> o = 8;> u = 9;> }>> if(output_mV > 299 && output_mV < 400)> {> o = 10;> u = 11;> }
so etwas würde ich immer "verdichten", ich hasse dieses sinnlose
klammern von "einzeiler" und auch die bedingung sinniger hinschreiben.
if (200 <= output_mV && output_mV < 300) o = 8, u = 9;
else if (300 <= output_mV && output_mV < 400) o = 10, u = 11;
mt
Karl schrieb:> was nützt es, geilen Code zu schreiben, der nur> von 10% der potentiellen Kollegen verstanden wird?
Zumal die 30 Originalzeilen (bei Blocksatz) gut lesbar sind.
Das C++ laufzeittechnisch super effektiv ist, für solche Dinge besser
als jede andere Sprache, geschenkt.
Bei solchen Beispielen wird klar, warum Funktion mit mehr als 10 Zeilen
böse sind und Unittests unverzichtbar.
Dr. Sommer schrieb:> Es gibt Kollegen die können C++.
Ja. Aber Wilhelm meint offenbar, man könnte auch als "normaler"
C-Programmierer ratzfatz auf C++ umsteigen. Dabei versucht er, mit
Tonnen von sehr fortgeschrittenem (aber leider auch unvollständigen und
damit oft nicht compilierbaren) C++17-Code sogar C-Anfänger für C++
umzustimmen.
Dass er mit seinen Beispielen, die eher wie Kanonen auf Spatzen wirken,
einen potentiellen C-nach-C++-Umsteiger eher abschreckt, scheint er
absolut zu ignorieren.
Peter (peda), der bekanntermaßen schon seit Jahren viele gute
C-Programme hier im Forum vorstellt und damit auch als C-Experte hier
bekannt ist, hat ja oben geschrieben, dass er bei Wilhelms Code nur noch
Bahnhof versteht. Dabei hat er vorher guten Willen gezeigt, Wilhelms
Code auch zu verstehen und auch nachzuvollziehen.
Wilhelm ignoriert das einfach und versucht gar nicht erst, Peters
Bedenken und Zweifel durch entsprechende Erklärungen und Hilfestellungen
zu zerstreuen - ganz im Gegenteil: Er ignoriert einfach Peters Beiträge,
um stattdessen auf Dr. Sommers Variante eine noch komplexere
C++-17-Version oben draufzulegen.
@Wilhelm: Warum gehst Du auf Peters Verständnisprobleme erst gar nicht
ein? Der einzige Eindruck, den Du damit hinterlässt: Du kaperst
C-Anfänger-Probleme-Threads, um dann C++ den Leuten madig zu machen,
indem Du möglichst komplexe Beispiele postest.
Warum zäumst Du das Pferd von hinten auf, statt in mehreren Schritten
vom einfachen Beispiel letztendlich zur eleganten Variante zu kommen?
Dann könnte man Deine Gedankengänge wenigstens nachvollziehen.
Voraussetzung ist natürlich:
- Angabe des Compilers
- Angabe der C++-Version (also bei Dir 17)
- Vollständig compilierbarer Code
Um möglichst viele Leute zu erreichen, wäre es auch nicht gerade dumm,
bei der C++-Version eher Abstriche zu machen und auch mal zu C++14 (oder
älter) zurückzugehen, wie es Dr. Sommer gemacht hat. Nicht jeder hat den
neuesten GCC auf seinem Rechner.
Aber so, wie Du das machst, wird das nichts. Solange Du einfach die
Leute ignorierst, die ihre Verständnisprobleme äußern und damit auch
Hilfestellungen Deinerseits erwarten, machst Du denen C++ nicht gerade
schmackhaft. Leider erreichst Du mit Deiner "Mission" das Gegenteil,
welches Du vermeintlich zu erreichen suchst.
Karl schrieb:> Bei allem Respekt vor euren c++ Kenntnissen, auf die ich schon ein> bisschen neidisch bin: was nützt es, geilen Code zu schreiben, der nur> von 10% der potentiellen Kollegen verstanden wird? Ich benutze auch> gerne einen Teil von c++, aber da ich ab und zu ein Produkt ausliefern,> weiter entwickeln oder gar warten muss, habe ich leider nicht in dem> Maße Zeit mich in neue c++e einzuarbeiten. Ich verstehe leider> vornehmlich Bahnhof.
Das erinnert an die viel zitierte Geschichte vom Förster und Holzfäller
...
Eine sehr einfaches, gut machbares, für jeden erreichbares und in jeder
Firma durchführbares Hilfsmittel sind das, was man früher "Standups"
nannte, die hier mal als Dailies bezeichnet werden:
https://www.fluentcpp.com/2017/04/04/the-dailies-a-new-way-to-learn-at-work
Frank,
ich hatte heute zweimal geschrieben, daß es bei Wilhelms Code normal
ist, wenn er aus einfachen Sachen Code macht, der in keiner Weise mehr
nachvollziehbar ist. Schließlich ist das jetzt in mehreren Threads schon
so gewesen. Und daß so eine Praxis reiner Wegwerfcode ist, weil
spätestens der Maintenanceprogrammierer danach das nicht mehr
durchdringen wird.
Beidemale hat einer Deiner Moderatorkollegen das kommentarlos gelöscht,
obwohl es genau darauf hinausläuft, was Du jetzt selber als Moderator
schreibst. Wieso?
Frank M. schrieb:> Peter (peda), der bekanntermaßen schon seit Jahren viele gute> C-Programme hier im Forum vorstellt und damit auch als C-Experte hier> bekannt ist, hat ja oben geschrieben, dass er bei Wilhelms Code nur noch> Bahnhof versteht.
Ja, das war sein Kommentar zum ersten Post von Dr. Sommer. Danach kam
allerdings keine konkrete Frage mehr.
> Wilhelm ignoriert das einfach und versucht gar nicht erst, Peters> Bedenken und Zweifel durch entsprechende Erklärungen und Hilfestellungen> zu zerstreuen - ganz im Gegenteil:
Fragen will auch gelernt sein.
> @Wilhelm: Warum gehst Du auf Peters Verständnisprobleme erst gar nicht> ein?
Dazu sollte er mal eine konkrete Frage stellen. Bahnhof reicht nicht.
Wer keine konkrete Frage stellen kann, hat sich nicht damit
auseinandergesetzt.
> Voraussetzung ist natürlich:>> - Angabe des Compilers> - Angabe der C++-Version (also bei Dir 17)> - Vollständig compilierbarer Code
Malen nach Zahlen führt kaum zu einem Erkenntnisgewinn (und wird hier in
dem Forum ja gerne als Arduino-like bezeichnet). Man liest sich den Code
durch und stößt auf etwas unbekanntes. Dann schaut man selbständig mal
nach was das sein könnte und konstruiert in seinem Umfeld mit seinen
Bezeichnern, etc. ein eigenes Beispiel. Wenn das nicht funktioniert,
dann kann nachfragen. Aber man muss schon eine Frage haben.
> Um möglichst viele Leute zu erreichen, wäre es auch nicht gerade dumm,> bei der C++-Version eher Abstriche zu machen und auch mal zu C++14 (oder> älter) zurückzugehen, wie es Dr. Sommer gemacht hat. Nicht jeder hat den> neuesten GCC auf seinem Rechner.
Im Interesse der Weiterbildung könnte man aber mal einen neueren dazu
installieren. Richtet ja keinen Schaden an.
> Aber so, wie Du das machst, wird das nichts. Solange Du einfach die> Leute ignorierst, die ihre Verständnisprobleme äußern und damit auch> Hilfestellungen Deinerseits erwarten, machst Du denen C++ nicht gerade> schmackhaft. Leider erreichst Du mit Deiner "Mission" das Gegenteil,> welches Du vermeintlich zu erreichen suchst.
Ich bin nicht angetreten, um zu missionieren. Wer das nicht interessant
findet, soll es halt ignorieren. Die anderen können ja fragen. Aber das
setzt natürlich voraus, dass man sich ausreichend mit den Dingen
beschäftigt. Anschauen, zurücklehnen, erkennen, das man nichts versteht,
Bahnhof sagen, und dann darauf warten, das es mundgerecht zerteilt wird:
nein, so läuft das nicht. Das ist eine Anspruchshaltung, die auch im
echten Leben nicht zum Erfolg führt.
Nop schrieb:> Beidemale hat einer Deiner Moderatorkollegen das kommentarlos gelöscht,> obwohl es genau darauf hinausläuft, was Du jetzt selber als Moderator> schreibst. Wieso?
Weil du eine bloße Anschuldigung hingeworfen hast, ohne irgendeine
Argumentation, pure Behauptung. (Unsinnige Behauptungen wie die über
den vorgeblichen „Maintenanceprogrammierer“ hast du dir ja selbst
diesmal nicht verkneifen können.)
Wenn du den riesigen Unterschied zwischen deinem „Beitrag“ und Yalus
recht ausführlicher und im Gegensatz zu dir durchaus sachlicher
Argumentation nicht siehst, sorry.
Merke: sowie in deinem Satz das Wort „immer“ als Beschreibung von
Verhaltensweisen eines anderen auftaucht, ist dieser eigentlich von
vornherein eine falsche Aussage, deren offenbar einziger Zweck dann
Polemik ist.
Jetzt lies dir bitte Yalus Argumentation nochmal durch.
Jörg W. schrieb:> Weil du eine bloße Anschuldigung hingeworfen hast, ohne irgendeine> Argumentation, pure Behauptung.
Mit anderen Worten, Du hast die Vorgeschichte in den anderen Threads
nicht mitbekommen. Kann passieren, aber das hättest Du nachfragen
können, statt einfach zu löschen. Abgesehen davon ist Franks Beitrag
ebenfalls Behauptung, denn er verlinkt auch nicht auf die relevanten
Threads im Sinne eines Quellennachweises.
Ich kann Dir ziemlich genau sagen, was der Unterschied ist: Frank ist
auch Moderator und ich nicht.
> (Unsinnige Behauptungen wie die über> den vorgeblichen „Maintenanceprogrammierer“ hast du dir ja selbst> diesmal nicht verkneifen können.)
Das ist keine unsinnige Behauptung, sondern Realität in der Industrie.
Wenn Du solche Projekte noch nicht erlebt hast, sei froh, aber
klassifizier es nicht als Unsinn. Die Anführungszeichen deuten darauf
hin, daß Du nicht einmal weißt, worum es geht.
Der Grundplot ist der, daß C++ zu komplex ist, als daß man ALLES
verstehen könnte. Wenn man nun wahllos 10 Programmierer hat, die alle
ihre 30% Verständnis mischen, dann muß der Maintenanceprogrammierer die
Obermenge von all dem können muß UND darin auch noch die Bugs finden
muß, die erst später auftreten.
Deswegen wird üblicherweise nur ein kleines Subset von C++ verwendet.
Selbst bei C wird das so gemacht, deswegen gibt es ja MISRA-C.
Wilhelm M. schrieb:> Das erinnert an die viel zitierte Geschichte vom Förster und Holzfäller> ...
Meinst du die?
https://www.motivate-yourself.de/geschichte-holzfaeller-waldarbeiter-saege-stumpf/
Da würde ich direkt widersprechen. Es geht nicht nur darum, zu wenig
Zeit zum Lernen zu haben, sondern diesen Zeitaufwand gegen die evtl
nötige mehrarbeit ohne das gelernte und den langfristigen wert des codes
abzuwägen.
Wenn alle Teilnehmer am Thread in einer Abteilung wären, könnte nur dr.
Sommer deinen Code verwenden. Toll.
Offtopic: Dein Auftreten finde ich unangenehm und ein bisschen
überheblich. Du scheinst zeigen zu wollen, wie gut du c++ beherrschst.
Das ist gelungen.
Die gezeigten C++ Beispiele sehen ja alle recht tolle aus. Aber es kommt
mir doch für die kleineren Sachen als etwas Overkill vor.
Wenn ichs mir richtig überlege, liebe ich Pedas Forum Codebeispiele. Die
sind immer pure Essenz. Oft am Anfang schwer zu verstehen, dann als
brilliant verstanden. Auch sind sie immer sehr Platz orientiert und
passen gut auf kleine uC. Als Vorbild finde ich daher seinen
Programmierstil und Ansatz sympatischer.
Das soll jetzt keine Kritik an C++ sein. Aber die Welt sollte groß genug
sein, damit jedes Tierchen sein Pläsierchen finden kann. Nicht jeder der
hier im Forum mitmacht ist ein SW Guru der damit seine Brötchen verdient
und damit auch im Schlaf sicher wandelt. Wenn doch vielmehr ein breites
Spektrum an Können in beiden Richtungen vorhanden ist.
Wenn man sich erinnert, daß C als ASM Ersatz in die Welt gerufen wurde,
müßte man eigentlich zugeben, daß C dann schon ein wahrer Luxus ist,
auch wenn man im neuesten C++ komplizierte Konstrukte einfacher in Code
kleiden kann und mächtige Möglichkeiten hat. Naja, wer's kann und sich
damit wohlfühlt und die Firma erwartet, daß man es kann, dann ist ja
alles gut.
Deshalb plädiere ich, C trotzdem noch nicht ganz abzuschreiben. Viele
Projekte können damit auch heutzutage noch bequem durchgezogen werden.
Und wem C in Fleisch und Blut übergegangen ist, der wird oft mit
esoterischen C++ sowieso lange keine Freude haben. Der Weg scheint
zumindest mir als sehr steinig zu sein.
Mfg,
Ein Heimlehrgangsprogrammierer
Nop schrieb:>> Weil du eine bloße Anschuldigung hingeworfen hast, ohne irgendeine>> Argumentation, pure Behauptung.>> Mit anderen Worten, Du hast die Vorgeschichte in den anderen Threads> nicht mitbekommen.
Die ist mir egal. Hier geht es um dein Auftreten in diesem
Thread. Das fiel für mich unter „vorsätzliche Störung des
Forenbetriebs“ (also: Trollbeitrag), da du eben einfach nur eine
bloße Behauptung provokativ hingeworfen hast.
> Kann passieren, aber das hättest Du nachfragen> können, statt einfach zu löschen.
Wie soll ich bitteschön bei dir nachfragen, wenn du keine Mailadresse
angeben magst?
Sorry. Genau dafür darf man auch bei anonymen Postings eine
Mailadresse hinterlegen: damit wir ggf. mal rückfragen können (jemand
anders sieht sie ja sowieso nicht). Wenn jemand auf diese Möglichkeit
verzichtet, dann gehe ich davon aus, dass er an Rückfragen nicht
interessiert ist.
Solchen Käse wie den jetzt hier gerade im Thread breitzutreten, ist
für das Forum einfach nur lästig und auch vom Betreiber ausdrücklich
unerwünscht.
> Abgesehen davon ist Franks Beitrag> ebenfalls Behauptung, denn er verlinkt auch nicht auf die relevanten> Threads im Sinne eines Quellennachweises.
Franks (sorry, mit Yalu verwechselt, der war weiter oben aktiv) Beitrag
ist Argumentation, nicht nur eine hingeschmissene Behauptung.
Nochmal: wenn du den himmelweiten Unterschied zwischen deinem und
seinem Beitrag nicht siehst, dann tut es mir leid, aber dann wundere
dich nicht, wenn wir sowas ggf. auch mal als linienüberschreitend
empfinden und rauswerfen.
> Ich kann Dir ziemlich genau sagen, was der Unterschied ist: Frank ist> auch Moderator und ich nicht.
Andersrum wird der Schuh draus: weil Frank eben bereits seit Jahren
mit einem guten Diskussionsstil aufgefallen ist, ist er Moderator
geworden.
>> (Unsinnige Behauptungen wie die über>> den vorgeblichen „Maintenanceprogrammierer“ hast du dir ja selbst>> diesmal nicht verkneifen können.)>> Das ist keine unsinnige Behauptung, sondern Realität in der Industrie.
Es ist alles mögliche Realität in der Industrie.
Das allein macht es nicht verallgemeinerungswürdig. (Btw., auch ich
bin „in der Industrie“ tätig, ich weiß also auch, wovon wir reden.)
> Der Grundplot ist der, daß C++ zu komplex ist, als daß man ALLES> verstehen könnte.
Das bestreitet gewiss keiner.
Anderen Sprachen geht das genauso.
Ich habe übrigens absolut nicht bestritten, dass ich Wilhelms
Programmbeispiele in der präsentierten Form nicht lehrreich finde;
wenn man sowas schon als Beispiel für andere hinschreiben will, dann
muss man es zumindest tiefergehend erläutern und/oder Kommentare
einfügen.
Es ging hier aber nicht um Inhalte, sondern die (also deine) Form
der Kritik. Es ist eben ein großer Unterschied, ob man eine Kritik
sachlich rüberbringen kann, oder Worte wie „immer“ und „schreibt
gern write-only Code“ dafür benutzt.
> Deswegen wird üblicherweise nur ein kleines Subset von C++ verwendet.
Welches sich natürlich je nach Organisation unterscheiden kann.
> Selbst bei C wird das so gemacht, deswegen gibt es ja MISRA-C.
MISRA ist erstens nicht der Nabel der Industrie (sondern nur eines
Teils der Industrie), zweitens ja durchaus auch zumindest in Teilen
umstritten.
Jörg W. schrieb:> Wie soll ich bitteschön bei dir nachfragen, wenn du keine Mailadresse> angeben magst?
So, wie Du es jetzt gerade auch tust. Im Übrigen bin ich nicht der
Einzige, dem es negativ auffällt, wenn Wilhelm öfter Threads mit
C++-Gespamme kapert. Das passiert jetzt nicht zum erstenmal, so daß es
mich schon überrascht, wenn Du davon noch gar nichts mitbekommen hast.
> Das allein macht es nicht verallgemeinerungswürdig. (Btw., auch ich> bin „in der Industrie“ tätig, ich weiß also auch, wovon wir reden.)
Maintenanceprogrammierer sind in der Industrie völlig normal. Mag sein,
daß der Begriff auf deutsch nicht üblich ist, aber da ich mehr englisch
als deutsch lese, fiel mir für "maintenance programmer" halt keine
bessere Übersetzung ein.
Ist doch auch logisch. Während der aktiven Entwicklung braucht man eben
deutlich mehr Entwickler. Irgendwann ist das Projekt aber fertig, dann
geht es um Pflege, Bugfixes und Erweiterungen. Dafür stellt aber keine
Firma mehr die volle Mannschaft hin, sondern das wird runtergefahren.
Zudem nimmt man dafür typischerweise auch eher die neu eingestellten
Leute.
> Es ging hier aber nicht um Inhalte, sondern die (also deine) Form> der Kritik. Es ist eben ein großer Unterschied, ob man eine Kritik> sachlich rüberbringen kann, oder Worte wie „immer“ und „schreibt> gern write-only Code“ dafür benutzt.
Wie gesagt, daß liegt daran, daß Wilhelm das in diesem Stil mit einiger
Regelmäßigkeit tut, und nach demselben Muster. Lies Dir die Reaktionen
doch durch hier. Wenn jemand versucht, über das Disassembly
rauszukriegen, was der Code eigentlich tut, ist das geradezu die
Definition von write-only-Code.
Ich mag mir gar nicht ausmalen, was für Code dabei wohl rauskäme, wenn
der auch noch inhaltlich anspruchsvolle Funktionen erfüllen sollte.
Und nein, das liegt nicht zwingend an C++ an sich, sondern es zieht
solche Leute nur verstärkt an. Der Code von Stockfish etwa, einer der
stärksten Schach-Engines der Welt, ist auch in C++ und sieht trotzdem
nicht so aus.
Nop schrieb:> Ich mag mir gar nicht ausmalen, was für Code dabei wohl rauskäme, wenn> der auch noch inhaltlich anspruchsvolle Funktionen erfüllen sollte.
Schon mal daran gedacht, daß sich manche Vorteile von mehr Abstraktion
bei "Blinky"-Äquivalent-Code noch nicht auswirken?
> Und nein, das liegt nicht zwingend an C++ an sich, sondern es zieht> solche Leute nur verstärkt an. Der Code von Stockfish etwa, einer der> stärksten Schach-Engines der Welt, ist auch in C++ und sieht trotzdem> nicht so aus.
Was ein Wunder für ein Stück Code, das 13 Jahre bevor C++17
verabschiedet wurde, entstand. Immerhin haben sie vereinzelt constexpr
nachgelegt. Das grundsätzliche Design basiert aber auf C++03.
Warum haben die das eigentlich noch nicht nach Rust portiert, das ist
doch viel hipper?
Weia, was für eine Beitrags-Flut...
Irgendwie nervt mich dieses Standard-Totschlag-Argument "die Kollegen
müssen das auch verstehen". Wenn man danach geht bleibt man ewig bei
C90, RCS und 8051 stecken. Das ist wie die sagenumwobene Glass Ceiling,
man kann sich nicht weiter entwickeln und bleibt immer auf dem selben
Stand. Irgendwann will man auch einfach mal was neues probieren und
nicht den 10000. String-Verarbeitungs-Algorithmus in C manuell schreiben
weil es in C nicht anders geht... Und es kann ja auch nicht sein dass
der einzige Weg dafür darin besteht zum PowerPoint-Entwickler zu werden.
Höhere Programmiersprachen wurden ja auch nicht zum Spaß erfunden, C ist
längst nicht mehr das Maß aller Dinge, da steckt auch viel Potential zur
Effizienz-Steigerung drin.
Wenn man hier im Forum ein C++ Beispiel zeigt will man zeigen wie es
auch geht ohne jetzt bei Adam und Eva anfangen und alles erläutern zu
wollen. Dazu gibt es Bücher und Tutorials. Blöd ist nur wenn es eher
abschreckend wirkt...
Heimlehrgangsprogrammierer schrieb:> Deshalb plädiere ich, C trotzdem noch nicht ganz abzuschreiben.
Oh, das passiert auch nicht. C ist halt viel Handarbeit, was immer dort
gut ist, wo die vielen hilfreichen aber komplizierten Schablonen anderer
Sprachkonzepte nicht so ganz passen.
Dr. Sommer schrieb:> C ist> längst nicht mehr das Maß aller Dinge,
wie wahr! beispiel, ich portiere gerade einige meiner quellen nach
micopython und bin beeindruckt von python auf "kleiner" hardware ...
mt
Frank M. schrieb:> Peter (peda), der bekanntermaßen schon seit Jahren viele gute> C-Programme hier im Forum vorstellt und damit auch als C-Experte hier> bekannt ist,
Bei allem Respekt, PeDa ist auch einer derjenigen, dessen Code schonmal
unleserlich geschrieben ist, um Zeilen oder auch Zeichen zu sparen.
Selbsterklärenden Code schreibt der auch nicht immer.
Und natülich treffen mit Peda als HardCore-K&R-C'ler und Wilhelm als
HardCore C++20'ler völlig verschiedene Welten aufeinander ;)
Oliver
Carl D. schrieb:> Schon mal daran gedacht, daß sich manche Vorteile von mehr Abstraktion> bei "Blinky"-Äquivalent-Code noch nicht auswirken?
Sagte ich ja, das wird noch schlimmer, wenn dahinter auch noch Funktion
steht. Genau das meinte ein gewisser Torvalds, als er bei Git nicht nur
kein C++ wollte, sondern auch C++-Programmierer draußenhalten. Obwohl
Git ja nun eindeutig nicht Kernel ist.
Dr. Sommer schrieb:> Irgendwie nervt mich dieses Standard-Totschlag-Argument "die Kollegen> müssen das auch verstehen".
Es ist halt nicht nur das reine Programmieren, sondern auch noch
Domänenwissen, was ebenfalls Jahre braucht. Zuguterletzt will sich auch
nicht jeder nach einem realen Arbeitstag auch noch in der Freizeit damit
endlos beschäftigen müssen. C hat den grundlegenden Vorteil, den C++
längst verloren hat - es ist eine kompakte Sprache, die man nicht nur in
der Breite, sondern auch in der Tiefe noch gut überschauen kann.
Aber in der realen Industrie mit Bezug zu embedded ist ja schon C zu
tricky, daher MISRA-C. Zumal dort auch erheblichenteils nicht
Informatiker tätig sind, aus guten Gründen.
Oliver S. schrieb:> Bei allem Respekt, PeDa ist auch einer derjenigen, dessen Code schonmal> unleserlich geschrieben ist, um Zeilen oder auch Zeichen zu sparen
Ich denke, das liegt vielmehr daran, dass PeDa in einer Zeit mit C
groß geworden ist, als sein 8051-Compiler noch viel blöder als der
Programmierer war. Damit hat der Programmierer dann „voroptimiert“.
Mit heutigen Compilern auf heutiger Hardware braucht man sowas nicht
mehr, da kann man eigentlich immer leserlichen Code schreiben.
Die Überschrift des TE war ja auch reichlich unglücklich gewählt: es
kam ihm ja gar nicht darauf an, den Code unleserlich zu machen,
sondern er meinte damit „unorthodox geschrieben“, letztlich aber, um
eine Verbesserung der Lesbarkeit zu erreichen.
Dr. Sommer schrieb:> Wenn man hier im Forum ein C++ Beispiel zeigt will man zeigen wie es> auch geht ohne jetzt bei Adam und Eva anfangen
Das verlangt ja auch keiner.
Nur sollten die Beispiele auch wenigstens compilierbar sein.
Und dazu gehört nunmal, daß man die minimal nötige Compilerversion
angibt, sowie auch alle benötigten privaten Header postet oder verlinkt.
Peter D. schrieb:> Dr. Sommer schrieb:>> Wenn man hier im Forum ein C++ Beispiel zeigt will man zeigen wie es>> auch geht ohne jetzt bei Adam und Eva anfangen>> Das verlangt ja auch keiner.> Nur sollten die Beispiele auch wenigstens compilierbar sein.> Und dazu gehört nunmal, daß man die minimal nötige Compilerversion> angibt, sowie auch alle benötigten privaten Header postet oder verlinkt.
Es ergeben sich hier zwei Probleme:
1) Target AVR: es existiert aber keine libstc++ für diese Target. Da
wird jeder seine eigene haben, oder manche benutzen auch
https://www.etlcpp.com (die ich selbst nicht verwende, da ich in meiner
Variante noch Optimierungen vorgenommen habe, manche Teile darf ich
nicht veröffentlichen, leider kein OSS)
2) In dem oben geposteten Beispiel tauchen Meta-Funktionen aus einer
(meiner) TMP-Bibliothek auf. Diese kann/darf ich leider nicht öffentlich
zur Verfügung stellen, auch leider kein OSS.
In Deinem Fall Peter gehe ich davon aus, dass Du als Target AVR hast.
Hier musst Du also erst mal Problem 1) lösen.
Wenn Du das geschafft hast, bleibt Problem 2). Der Code wird an ein paar
wenigen Stellen nicht compilieren. Hier kann ich gerne helfen, ohne dass
ich die ganze TMP-Bibliothek zur Verfügung stellen muss. Dies wäre auch
gleichzeitig ein guter Einstieg in TMP.
Wobei ich der Meinung bin, dass die Funktion von
1
usingx=Meta::pop_front<list>;
klar sein sollte. Wenn man die libstdc++ kennt, hat man mindestens mal
eine Vermutung, was das macht. Wenn das nicht der Fall ist, musst Du
Dich zunächst einmal mit TMP beschäftigen. Ansonsten ist der Lerneffekt
wieder null.
Bottom line: zuerst Problem 1 lösen unabhängig von den hier gezeigten
Beispielen (oder anderes Target wählen), dann Problem 2 angehen mit
Wissen über TMP.
Wilhelm M. schrieb:> Diese kann/darf ich leider nicht öffentlich zur Verfügung stellen, auch> leider kein OSS.
Dann veröffentliche doch bitte auch keine Beispiele, die darauf
aufsetzen, das hat doch sonst keinerlei Wert für die Community.
Wenn schon, dann liefere halt Rewrites für die entsprechenden Teile.
Dein Problem #1 kann man getrost erstmal zur Seite schieben, solange
sich der Kram dann wenigstens auf dem PC compilieren lässt, denn dann
lässt sich das Beispiel zumindest nachvollziehen. Selbst für Leute,
die primär sonst auf Controllern arbeiten, schadet es ja nicht, wenn
man irgendeine Demonstration zuerst einmal nur auf dem PC machen
kann. Ob und wann und unter welchen Umständen man sowas auf eine
Controllerplattform transferieren will, kann dann allemal jeder selbst
entscheiden.
Solange du aber Dinge postest, die ohnehin keiner nachvollziehen kann,
hinterlässt das eben eher den Beigeschmack von Angeberei als den, dass
du anderen Leuten „auf die Sprünge“ helfen möchtest.
Jörg W. schrieb:> Wilhelm M. schrieb:>> Diese kann/darf ich leider nicht öffentlich zur Verfügung stellen, auch>> leider kein OSS.>> Dann veröffentliche doch bitte auch keine Beispiele, die darauf> aufsetzen, das hat doch sonst keinerlei Wert für die Community.
Ok, dann lösche bitte alle meine vorigen Beiträge in diesem Thread!
>> Wenn schon, dann liefere halt Rewrites für die entsprechenden Teile.
Sonst noch Wünsche?
> Solange du aber Dinge postest, die ohnehin keiner nachvollziehen kann,> hinterlässt das eben eher den Beigeschmack von Angeberei als den, dass> du anderen Leuten „auf die Sprünge“ helfen möchtest.
Wer Fragen zu TMP hat, soll dann einfach einen neuen Thread aufmachen,
und ganz groß C++ oben drüber schreiben, damit keine auf die Idee kommt,
irgendwelchen C oder Basic Code dort zu posten (was mch persönlich nicht
stören würde).
So, und nun bitte löschen (bis auf diesen hier).
Wilhelm M. schrieb:>> Wenn schon, dann liefere halt Rewrites für die entsprechenden Teile.>> Sonst noch Wünsche?
Alternativ auf eine der 982 OSS-TMP-Libraries umschreiben wie Boost.Hana
...
Wilhelm M. schrieb:> Ich bin nicht angetreten, um zu missionieren. Wer das nicht interessant> findet, soll es halt ignorieren. Die anderen können ja fragen.
Du hattest ja seinerzeit den sehr interessanten und mitunter lehrreichen
Thread
Beitrag "Informationen zu C vs C++ / aka Futter für die Diskussion"
gestartet, der auch heute noch regelmäßig neue Beiträge erfährt.
Kannst Du Dir eventuell vorstellen, dass Du dort eine interessiertere
und kompetentere Leserschaft findest als in solchen Trivial-C-Frage
Threads wie
Beitrag "switch(Funktion()) möglich?"
oder
Beitrag "Code unleserlich schreiben um Zeilen zu sparen." ?
Hier kommt jemand mit einer sehr einfachen Frage zu C, die dem Leser
direkt offenbart, dass der TO in Sachen C wahrscheinlich nicht nur
ziemlicher Anfänger ist, sondern gern auch hilfreiche Tipps zu seiner
Frage von den erfahrenen C-Programmierern wünscht.
Ich kann mir in beiden Fällen leider überhaupt nicht vorstellen, dass
der jeweilige TO, der sowieso schon mit C seine liebe Müh hat, aufgrund
Deiner intellektuell sehr anspruchsvollen C++-17-Code-Snippets nun sagen
wird: "Wilhelm hat Recht! Ich schmeiße C hin, nehme C++-17 und all meine
Probleme sind gelöst! Alles total easy!"
Ich habe jedenfalls in beiden oben genannten Threads keinerlei Reaktion
der beiden TOs erkannt - ganz im Gegenteil: Als die Diskussion über die
C++-Alternativen anfing, haben sich die TOs flugs aus dem Thread
ausgeklinkt, einfach, weil es sie vermutlich intellektuell in diesem
Stadium ihres Programmierer-Daseins absolut überforderte.
Das Problem, was ich dann als Moderator sehe: Der Thread driftet
komplett ab. Das eigentliche Thema tritt dann in den Hintergrund.
Stattdessen wird der ursprüngliche Trivial-C-Thread mit höchst
anspruchsvollem C++-17-Code regelrecht geflutet. Diesen Eindruck kann
man jedenfalls als Leser, den das ursprüngliche C-Thema interessiert,
durchaus gewinnen. Dieses Vorgehen mag dann in dem einen oder anderen
Auge des Betrachters gar als Kaperung oder sogar als "Spam" angesehen
werden.
Deshalb möchte ich Dir folgenden Vorschlag für solche Fälle für die
Zukunft machen:
Wenn Du für ein Trivial-C-Problem eine elegante C++-17-Lösung siehst,
die durchaus erwähnenswert ist, verlinkst Du vom Trivial-C-Thread nach
Beitrag "Informationen zu C vs C++ / aka Futter für die Diskussion"
um dort Deine C++-17-Variante weiterzudiskutieren.
Wäre das ein annehmbarer Vorschlag? In meinen Augen schon, denn dann
würden solche emotionsgeladenen Reaktionen wie hier erst gar nicht
auftreten.
P.S.
Ich schreibe oben mit Absicht nicht C++, sondern C++-17, da die hier
geposteten Code-Snippets allesamt inkompatibel zu älteren bzw. zu den
meisten auf dem Markt eingeführten C++-Versionen sind.
Wilhelm M. schrieb:> Ansonsten ist der Lerneffekt wieder null.
Ich finde den Anspruch, das andere vorab was lernen sollen, nicht
gerechtfertigt. Man sollte doch erst mal sehen, dass ein Problem
eleganter gelöst ist. Wenn es hingegen komplexer und objektiv schwerer
lesbar ist, ... wieso dann noch eintauchen? Zumal C++ hier ja meist der
Optimierung (Speicher und Laufzeit) dient.
Wenn Standard-C++ Standardschablonen für ein Problem hat: Super.
Aber das Argument, dass Du eigene Schablonen für ein Problem hast oder
erstellen kannst, ... Ich las hier einige Threads (ohne Autoren oder
Sprachen zu erinnern), wo ein überschaubares Problem "vereinfacht"
wurde, indem es hinter einer Funktion versteckt wurde, deren
Implementierung dann dem Leser überlassen hat :-)
Wilhelm M. schrieb:> 2) In dem oben geposteten Beispiel tauchen Meta-Funktionen aus einer> (meiner) TMP-Bibliothek auf. Diese kann/darf ich leider nicht öffentlich> zur Verfügung stellen, auch leider kein OSS.
Es wäre schön gewesen, wenn das gleich über den Beispielen gestanden
hätte.
Gerade einem Anfänger fällt es schwer, zu erkennen, was ist aus
Standardlibs des Compilers und was nicht.
Frank M. schrieb:> Deshalb möchte ich Dir folgenden Vorschlag für solche Fälle für die> Zukunft machen:>> Wenn Du für ein Trivial-C-Problem eine elegante C++-17-Lösung siehst,> die durchaus erwähnenswert ist, verlinkst Du vom Trivial-C-Thread nach>> Beitrag "Informationen zu C vs C++ / aka Futter für die Diskussion">> um dort Deine C++-17-Variante weiterzudiskutieren.
Die Idee, Frank, wird so aber nicht zünden, denn in diesen Thread
schauen die C Programmierer nicht hinein. Eigentlich war es mein Wunsch,
in dem o.g. Thread auch nur Verweise auf andere (bessere) Quellen zu
verlinken. Dort erwähne ich ja auch des öfteren, dass die eigentlichen
Diskussion besser in anderen, leichter sichtbaren Thread geführt werden
sollten.
> Wäre das ein annehmbarer Vorschlag? In meinen Augen schon, denn dann> würden solche emotionsgeladenen Reaktionen wie hier erst gar nicht> auftreten.
Aber Frank, ich finde es sehr gut, dass Du Dir wirkliche, konstruktive
Gedanken machst!
Ich stehe zu meiner Grundaussage: "Stop teaching C". Nicht wegen der
Sprache C im engeren Sinne, sondern weil der Blick für die
Grundprinzipien des Programmierens verloren geht. Das gilt übrigens auch
- und das ist die eigentliche Aussage des Spruchs - wenn man mit dem C
in C++ beginnt.
Wer nicht in größeren Dimensionen denkt, kann an trivialen Beispielen
den eigentlichen Wert der meisten Beispiele und Umsetzung in
C++(17/20/..) nicht erkennen.
Bitte nicht falsch verstehen, denn ich bin nicht emotionsgeladen an
dieser Stelle, aber ich werde in Zukunft immer nachfragen, ob auch
Interesse an einem Ansatz (in C++) besteht.
Ich möchte jetzt aber dennoch meinem Wunsch nochmals starken Nachdruck
verleihen, meine Beiträge in diesem Thread zu löschen. Ich weiß, dass
Euch das Nutzungsrecht gehört, aber ich bitte einfach darum.
Wilhelm M. schrieb:> Ich möchte jetzt aber dennoch meinem Wunsch nochmals starken Nachdruck> verleihen, meine Beiträge in diesem Thread zu löschen. Ich weiß, dass> Euch das Nutzungsrecht gehört, aber ich bitte einfach darum.
Vielleicht überlegst Du dir das ja nochmal, wenn Du auch andere Stimmen
hörst?
Ich persönlich habe überhaupt kein Problem mit diesem Thread. Im
Gegenteil, ich hab' ihn genossen.
Der TO hat schon sehr früh erschöpfend Auskuft bekommen. Wahrscheinlich
mehr als er eigentlich wissen wollte. So what? Ab da kann man sich
anderen Dingen widmen.
Auch wenn ich persönlich nicht alles gut und richtig finde, was an
"neuem" C++ so kommt, selbst hauptsächlich in C programmiere (und daran
in absehbarer Zeit wahrscheinlich auch nichts ändern werde), finde ich
doch alles, was man "dazulernen" kann, gut und richtig. Ich muss es ja
nicht verwenden, wenn ich (für mich) das Gefühl habe, das es nicht
passt. Wem's gar nicht passt, der muss es nicht mal lesen.
Wenn dieses (Diskussions-) Forum nur noch Beiträge toleriert, die 100%ig
auf die gestellte Frage eingehen, verliert es (für mich) gewaltig an
Wert. Meist entstehen die wirklich interessanten Fragen und Antworten
gerade erst aus der Diskussion.
"Rummäkler" mäkeln meiner Ansicht nach oft genug lediglich aus
verletzter Eitelkeit mit Neid ("der kann was, was ich nicht mal
verstehe, das muss also akademischer Mist sein").
Da solltest Du drüber stehen. Kompetenz klingt halt nun manchmal
arrogant ... ;)
Markus F. schrieb:> Wenn dieses (Diskussions-) Forum nur noch Beiträge toleriert, die 100%ig> auf die gestellte Frage eingehen, verliert es (für mich) gewaltig an> Wert. Meist entstehen die wirklich interessanten Fragen und Antworten> gerade erst aus der Diskussion.>> "Rummäkler" mäkeln meiner Ansicht nach oft genug lediglich aus> verletzter Eitelkeit mit Neid ("der kann was, was ich nicht mal> verstehe, das muss also akademischer Mist sein").>> Da solltest Du drüber stehen. Kompetenz klingt halt nun manchmal> arrogant ... ;)
da bin ich voll dabei!
ich lese alles zu c++ und archiviere sogar die beipiele, die ich heute
zugegebenerweise absolut nicht verstehe, aber irgendwann mal
nachvollziehen möchte.
was mich richtig stört, ist die nivellierung nach unten und nicht die
vereinzelten "leuchtenen blüten"! ich würde gerne sehen, dass das forum
einen einsteiger- UND "experten" -bereich schaft.
also hört bitte auf damit, das niveau immer weiter nach unten zu
drücken, z.b. mit der begründung das jeder es verstehen soll.
ich denke, dass der niveauverfall in der gesellschft gewünscht und
gefördert wird. aber ich wehre mich dagegen - soll heisen was/wer
schrott/doof ist wird auch so benannt und nicht immer nur schön reden.
mt
Wilhelm M. schrieb:> Die Idee, Frank, wird so aber nicht zünden, denn in diesen Thread> schauen die C Programmierer nicht hinein.
Richtig. Vielleicht wäre es auch eine Idee, C-Programmierern nicht
permanent mit C++ auf den Senkel zu gehen. Dieses Missionieren ist
einfach nur lästig.
> aber ich werde in Zukunft immer nachfragen, ob auch> Interesse an einem Ansatz (in C++) besteht.
Ich fände es schön, wenn Du das in C-Threads einfach seinläßt. Du
fändest es umgedreht auch störend, wenn Du über C++ reden willst und
dann C-Programmierer stattdessen darüber diskutieren, daß das
schlichtweg Obfuscation ist.
Frank M. schrieb:> Ich kann mir in beiden Fällen leider überhaupt nicht vorstellen, dass> der jeweilige TO, der sowieso schon mit C seine liebe Müh hat, aufgrund> Deiner intellektuell sehr anspruchsvollen C++-17-Code-Snippets nun sagen> wird: "Wilhelm hat Recht! Ich schmeiße C hin, nehme C++-17 und all meine> Probleme sind gelöst! Alles total easy!"
Eines habe ich übrigens durchaus daraus gelernt, nämlich was offenbar
der Hintergrund war, wieso Torvalds in seinem bekannten Rant zum Thema
"Git in C?" schrieb "even if the choice of C were to do nothing but
keep the C++ programmers out, that in itself would be a huge reason to
use C."
Nunja, einfach damit das Projekt eben nicht mit solchem Code endet wie
demonstriert.
Nop schrieb:> Ich fände es schön, wenn Du das in C-Threads einfach seinläßt. Du> fändest es umgedreht auch störend, wenn Du über C++ reden willst und> dann C-Programmierer stattdessen darüber diskutieren, daß das> schlichtweg Obfuscation ist.
Hier besteht ein logisches Problem:
Du willst die C++ Beiträge nicht sehen, deswegen sollen sie nicht
geschrieben werden. Andere Teilnehmer wollen die Beiträge aber lesen
(und zwar in genau dem Zusammenhang, in dem sie jetzt stehen).
Lösung:
Die Beiträge werden weiterhin geschrieben und DU (und alle die ebenfalls
nicht interessiert sind) ignorierst sie.
mh schrieb:> Lösung:> Die Beiträge werden weiterhin geschrieben und DU (und alle die ebenfalls> nicht interessiert sind) ignorierst sie.
Schön, dann kann man auch jeden Thread mit anderem peripher
interessantem Offtopic zumüllen. Kann man ja überlesen, oder?
Nop schrieb:> Schön, dann kann man auch jeden Thread mit anderem peripher> interessantem Offtopic zumüllen. Kann man ja überlesen, oder?
Ich sehe kein Problem wenn sich die Diskussion in eine andere Richtung
bewegt, wenn genügend Teilnehmer daran interessiert sind.
Und C++ Alternativen zu C Beispielen sind nun wirklich kein Offtopic in
einem Thread der sich "Code unleserlich schreiben um Zeilen zu sparen"
nennt.
mh schrieb:> Und C++ Alternativen zu C Beispielen sind nun wirklich kein Offtopic in> einem Thread der sich "Code unleserlich schreiben um Zeilen zu sparen"> nennt.
Wobei danach das „unleserlich“ vom TE korrigiert worden ist: es sollte
durchaus besser lesbar werden, so die Intention. Dahingehend ist
manches der C++-Beispiele durchaus nicht gerade on-topic :), auch wenn
es vielleicht mehr „Coolheitsfaktor“ hat oder halt auch Arbeit spart,
wenn sich am Algorithmus zur Generierung der Daten mal was ändert
(wofür man im Original hätte die komplette Tabelle händisch neu
tippen müssen).
Jörg W. schrieb:> wenn sich am Algorithmus zur Generierung der Daten mal was ändert
Sowas ist z.B. praktisch für CRC-Tabellen (mit welchen man den
CRC-Algorithmus stark beschleunigen kann); die kann man per
constexpr-Algorithmus generieren und so spart man sich endlose
Zahlenfolgen im Code. Wenn man einen Parameter zur Erzeugung ändern will
kann man das im Code schnell abändern und muss keine externen Tools
anwerfen. Leider gibt's ja Protokolle die so vermurkste
Nicht-Standard-CRC's nutzen die man nicht mit den CRC-Hardwareeinheiten
von Mikrocontrollern erzeugen kann, wie z.B. beim LTC6804.
Dr. Sommer schrieb:>> wenn sich am Algorithmus zur Generierung der Daten mal was ändert>> Sowas ist z.B. praktisch für CRC-Tabellen (mit welchen man den> CRC-Algorithmus stark beschleunigen kann)
Nur: gerade diese legt man in der Regel genau einmal an, danach
sollten sie sich nicht mehr ändern. :)
Jörg W. schrieb:> Nur: gerade diese legt man in der Regel genau einmal an, danach> sollten sie sich nicht mehr ändern. :)
Na, sobald man einen anderen Kommunikationspartner mit anderen
Sonderwünschen an die CRC hat muss man sie neu anlegen...
Jörg W. schrieb:> mh schrieb:>> Und C++ Alternativen zu C Beispielen sind nun wirklich kein Offtopic in>> einem Thread der sich "Code unleserlich schreiben um Zeilen zu sparen">> nennt.>> Wobei danach das „unleserlich“ vom TE korrigiert worden ist: es sollte> durchaus besser lesbar werden, so die Intention. Dahingehend ist> manches der C++-Beispiele durchaus nicht gerade on-topic :),
Nun ja, in einem Thread, wo das Topic erst x ist und anschließend !x,
ist es per se ein wenig schwierig, on-topic zu bleiben, nicht wahr?
Also mir ist das Beispiel Programm von Wilhelm "unheimlich". Wenn man da
nicht wirklich ein solide C++ Grundlage, Verständnis und
Erinnerungsvermögen an die Sprachelemente und Beziehungen hat, ist es
dem Uneingeweihten praktisch unmöglich das Programm funktionell im
Detail zu untersuchen. Beim alten C ist praktisch alles offen und man
kann ein Programm sehr gut analysieren. Beim obigen Beispiel ist alles
hinter den Regeln und Sprachen Design Details versteckt. Als C++
Anfänger tut man sich dann richtig schwer die pertinenten Daten Details
und Zusammenhänge zu verstehen und verfolgen. Die "Aha" Momente muss man
sich als Laie hier schwer erarbeiten und kommen leider nur recht selten.
Wer da professionell tagtäglich mit dem neuesten C++ arbeitet, womöglich
noch einige Universitätskurse abgelegt hat, für den ist das natürlich
alltäglich und in Fleisch und Blut übergegangen. Also seid geduldig mit
dem Rest der Welt der diesen tiefen Einblick in die neuen
Sprachentwicklungen nicht immer hat. Was Euch selbstverständlich ist,
ist für den Rest der Welt oft nur noch "Bahnhof".
OK. Und jetzt trampelt bitte nicht zu sehr auf mich herum. Ich fand
diese Erörterungen durchaus sehr interessant. Aber im Augenblick muss
ich einen sehr großen Bogen um die Materie machen:-)
Schönen Tag noch,
Gerhard
Markus F. schrieb:> Nun ja, in einem Thread, wo das Topic erst x ist und anschließend !x
War es ja nicht wirklich, und wer die Beiträge des TE aufmerksam
gelesen hatte, dem wurde das schnell klar.
Seine Überschrift war halt nur arg ungeschickt ausgedrückt.
Vielleicht noch zwei Sachen zu der ganzen Thematik und Aufregung hier:
In dem Beitrag
Beitrag "Re: Code unleserlich schreiben um Zeilen zu sparen."
hatte ich vollständigen und funktionierenden Code gepostet, mit einer
kleinen Ausnahme, die ich dort auch beschrieben hatte: und zwar
Util::sort() aus dem Include-File "util/algorithm.h". Dazu hatte ich
geschrieben, dass es ein constexpr Bubble-Sort sein dürfte.
Meine Schlußfolgerung daraus war / ist: es hat niemand, der sich hier
beschwert hat, jemals ausprobiert, den Code in einer C++17 Umgebung zu
kompilieren. Hätte das jemand versucht, dann wäre es ihm wie beschrieben
ausgefallen und er hätte es lediglich auskommentieren müssen. Den die
Eingangsdaten des Algorithmus waren bereits sortiert. Oder eben ein
Bubble programmieren. Hey Leute, das war doch machbar oder?
Zum anderen warte ich auch eine Antwort eines der hier mitlesenden /
mitpostenden Moderatoren zu meinem nachdrücklichen Wunsch, meine
Beiträge hier zu löschen. Da ist leider nichts erfolgt.
Wilhelm M. schrieb:> Meine Schlußfolgerung daraus war / ist: es hat niemand, der sich hier> beschwert hat, jemals ausprobiert, den Code in einer C++17 Umgebung zu> kompilieren. Hätte das jemand versucht, dann wäre es ihm wie beschrieben> ausgefallen und er hätte es lediglich auskommentieren müssen.
Ich habe mal nachgesehen welche GNU Version für Windows erhältlich ist
und wenn ich es nicht falsch interpretiert habe, ist V5.1 die neueste
Version die allerdings bis C++14 unterstützt. V8 mit C++17 scheint es im
Augenblick nur für Linux zu geben. Wie gesagt ich kenne mich mit den
erhältlichen Versionen nicht so aus. V4.92 ist die neueste Version die
ich im Betrieb habe.
https://sourceforge.net/projects/tdm-gcc/files/latest/download
Gibt es eine C++17 Windows Version und kann man sich eine Windows
kompatible C++17 installieren?
Wilhelm M. schrieb:> Zum anderen warte ich auch eine Antwort eines der hier mitlesenden /> mitpostenden Moderatoren zu meinem nachdrücklichen Wunsch, meine> Beiträge hier zu löschen.
Finde zumindest ich unpassend. Dann müsste man einen ziemlich großen
Teil der Diskussion, die sich rundherum entsponnen hat, löschen, denn
die hat losgelöst keinen Sinn. Deine Beiträge verstoßen ja auch nicht
gegen die Nutzungsbestimmungen, sie sind eben (m. E.) nur nicht so
hilfreich, wie sie sein könnten, wenn sie auch jeder compilieren
kann (ok, jeder, den es interessiert).
Gerhard O. schrieb:> Wilhelm M. schrieb:>> MinGW / CygWin hat gcc-8.1 (C++2a)>> Danke!
Bei Cygwin ist es doch nur 7.3, sorry! Aber das sollte auch reichen.
Ansonsten: VM / ArchLinux
Wilhelm M. schrieb:> Bei CygWilhelm M. schrieb:> Gerhard O. schrieb:>> Wilhelm M. schrieb:>>> MinGW / CygWin hat gcc-8.1 (C++2a)>>>> Danke!>> Bei Cygwin ist es doch nur 7.3, sorry! Aber das sollte auch reichen.>> Ansonsten: VM / ArchLinux
OK. Danke für die Berichtigung.
Markus F. schrieb:> "Rummäkler" mäkeln meiner Ansicht nach oft genug> lediglich aus verletzter Eitelkeit mit Neid ("der> kann was, was ich nicht mal verstehe, das muss> also akademischer Mist sein").
Die Unverständlichkeit vieler Computerthemen ist
meiner Erfahrung nach nicht ihrer tatsächlichen
Kompliziertheit geschuldet, sondern der Unfähigkeit
bzw. der Unlust der Missionare, sich allgemein-
verständlich auszudrücken.
Die Geschichte der Informatik ist die Geschichte
schlechter Begriffsbildungen und hirnrissiger
Erklärungen.
Wenn ich Potenzial hinter einem Konzept erkenne, bin
ich durchaus lernwillig. Ich bin aber nicht bereit,
als Initiationsritus unter Schmerzen irgend einen
Gehirnkrampf auswendig zu lernen, nur um dazuzugehören.
Nop schrieb:> Carl D. schrieb:>>> Schon mal daran gedacht, daß sich manche Vorteile von mehr Abstraktion>> bei "Blinky"-Äquivalent-Code noch nicht auswirken?>> Sagte ich ja, das wird noch schlimmer, wenn dahinter auch noch Funktion> steht.
Das Prinzip von unterschiedlichen fixen und variablen Kosten und der
Punkt (meist etwas oberhalb von trivial) an dem "wenig fix/viel
variabel" Dei Variante "viel fix/wenig variabel" kostenmäßig überholt,
sollte auch nicht-BWLern geläufig sein. Naja, vielleicht auch nicht,
wenn nicht mal mein einfacher Satz für jeden sinnbegreifend lesbar ist.
> Genau das meinte ein gewisser Torvalds, als er bei Git nicht nur> kein C++ wollte, sondern auch C++-Programmierer draußenhalten. Obwohl> Git ja nun eindeutig nicht Kernel ist.
Wenn es um Linux (und auch GIT) geht, mag man ihn für einen Gott halten,
er ist aber sicher nicht unfehlbar.
Jörg W. schrieb:> Dr. Sommer schrieb:>>> wenn sich am Algorithmus zur Generierung der Daten mal was ändert>>>> Sowas ist z.B. praktisch für CRC-Tabellen (mit welchen man den>> CRC-Algorithmus stark beschleunigen kann)>> Nur: gerade diese legt man in der Regel genau einmal an, danach> sollten sie sich nicht mehr ändern. :)
Wenn man aber den Rechenweg hinschreibt, dann ist man einen Level
weiter.
Es gibt z.B. 1Wire-Slave Implementierungen für AVR, da steht dann:
"wenn die ID geändert wird, bitte online via <link> den neuen CRC-Wert
berechnen. Oder es steht ein constexpr constructor eine OneWireId Klasse
da, der die CRC-Berechnung zur Compilezeit macht.
Das ist nur ein kleines Beispiel.
Man kann z.B. auf STM32 4 Bits eines LCD-Daten-"Worts" beliebig auf
einem 16bit-Port anordnen und zur Compile-Time eine LUT mit 16 Werten
für das BSRR (Bit Set/Reset Register) erzeugen, die dann per "echten
Wert" indiziert, die passenden Pins befüllt. Wohlgemerkt beliebige
Verteilung der Pins innerhalb des Ports.
Bei jedem dieser Beispiele bekommt man dann von "mitfiebernde"
anerkennende Wort, von den anderen die Ausrede, das geht doch in xyz so
und muß nicht anders sein.
Wenn es so wäre, daß nicht die Summe der komplizierten Detail unser
Rechenspielzeuge ausmachen würde, dann wäre ein Abakus immer die beste
Lösung.
Possetitjel schrieb:> Markus F. schrieb:>>> "Rummäkler" mäkeln meiner Ansicht nach oft genug>> lediglich aus verletzter Eitelkeit mit Neid ("der>> kann was, was ich nicht mal verstehe, das muss>> also akademischer Mist sein").>> Die Unverständlichkeit vieler Computerthemen ist> meiner Erfahrung nach nicht ihrer tatsächlichen> Kompliziertheit geschuldet, sondern der Unfähigkeit> bzw. der Unlust der Missionare, sich allgemein-> verständlich auszudrücken.
In seltene Fällen aber auch am Unvermögen bzw der Unlust der
Missionierten, sich auf neues einzulassen.
> Die Geschichte der Informatik ist die Geschichte> schlechter Begriffsbildungen und hirnrissiger> Erklärungen.
Die ganze Geschichte von Wissenschaft und Technik zeigt, daß es auch mal
ein/zwei Generationen Dauern kann, bis Spezialwissen zum Allgemeingut
wird. Im Mittelalter wäre man für das Verbreiten von C++-Knowhow
verbrannt worden.
> Wenn ich Potenzial hinter einem Konzept erkenne, bin> ich durchaus lernwillig. Ich bin aber nicht bereit,> als Initiationsritus unter Schmerzen irgend einen> Gehirnkrampf auswendig zu lernen, nur um dazuzugehören.
Manchmal kann der Erkenntnisstand der "Pioniere" aber nicht auf
Nachzügler warten.
Possetitjel schrieb:> Markus F. schrieb:>>> "Rummäkler" mäkeln meiner Ansicht nach oft genug>> lediglich aus verletzter Eitelkeit mit Neid ("der>> kann was, was ich nicht mal verstehe, das muss>> also akademischer Mist sein").>> Die Unverständlichkeit vieler Computerthemen ist> meiner Erfahrung nach nicht ihrer tatsächlichen> Kompliziertheit geschuldet, sondern der Unfähigkeit> bzw. der Unlust der Missionare, sich allgemein-> verständlich auszudrücken.
Jede Fachdisziplin hat ihr eigenes Idiom. Die Mediziner sind da ganz
weit "vorn", indem sie ihre Idiome in Latein/Griechisch ausdrücken. Dei
den Informatikern ist es überwiegend Englisch, wenn man "pipe" nicht mit
"Rohr" zwanghaft ins Deutsche übersetzen will.
Wir reden von Klassen, Funktionen, Elementfunktionen, Methode,
Nachricht, Datentypen, abstrakte Datentypen, generische Datentypen,
Objekten, Instanzen, Exemplaren und alles hat eine ziemlich festgelegte
Bedeutung. Je nach Kontext kann die eine oder andere Ausprägung eines
Begriffes im Vordergrund stehen.
Im allgemeinen ist es verständlicher, sich in dem zur Fachdisziplin
gehörenden Idiom auszudrücken, weil es prägnanten ist und man deswegen
weniger umschreiben muss: man sagt einfach "FiFo" oder "FiFo-ordered
Queue" statt: die Datenstruktur, die zwei (mindestens) Operationen
anbietet; eine, um Elemente anzufügen und eine, um Elemente zu
entfernen.
> Die Geschichte der Informatik ist die Geschichte> schlechter Begriffsbildungen und hirnrissiger> Erklärungen.
Beispiele?
Carl D. schrieb:> Das Prinzip von unterschiedlichen fixen und variablen Kosten und der> Punkt (meist etwas oberhalb von trivial) an dem "wenig fix/viel> variabel" Dei Variante "viel fix/wenig variabel" kostenmäßig überholt,> sollte auch nicht-BWLern geläufig sein.
Mag sein, daß man für größere Projekte tatsächlich C++ braucht. Aber
kleinere Projekte wie etwa der Linuxkernel mit 25 Millionen Codezeilen
gehen auch ganz gut in C, dann hat man auch nicht den ganzen Quatsch von
C++.
Wilhelm M. schrieb:> Possetitjel schrieb:>> Markus F. schrieb:>>>>> "Rummäkler" mäkeln meiner Ansicht nach oft genug>>> lediglich aus verletzter Eitelkeit mit Neid ("der>>> kann was, was ich nicht mal verstehe, das muss>>> also akademischer Mist sein").>>>> Die Unverständlichkeit vieler Computerthemen ist>> meiner Erfahrung nach nicht ihrer tatsächlichen>> Kompliziertheit geschuldet, sondern der Unfähigkeit>> bzw. der Unlust der Missionare, sich allgemein->> verständlich auszudrücken.>> Jede Fachdisziplin hat ihr eigenes Idiom.
Klar. Präzise Fachsprache ist wichtig und sinnvoll.
> Die Mediziner sind da ganz weit "vorn", indem sie ihre> Idiome in Latein/Griechisch ausdrücken.
Sehr gutes Beispiel: In der Medizin kann man am lebenden
Objekt studieren, wie man Sprache als Waffe verwendet, um
sich abzugrenzen und anderen auszuschließen.
(Soweit ich weiss, war das Ziel, vom Status des Jahrmarkts-
gauklers wegzukommen und sich äußerlich sichtbar der
Gelehrtenwelt anzugliedern, ein wesentlicher Grund dafür,
dass Chirurgen und ähnliche Leute begonnen haben, Lateinisch
zu reden. Es ging dabei nicht nur um Fachsprache, sondern
sehr wesentlich auch um sozialen Status. Und das hat, wie
man an den "Göttern in Weiss" sieht, auch funktioniert.)
> Dei den Informatikern ist es überwiegend Englisch, wenn> man "pipe" nicht mit "Rohr" zwanghaft ins Deutsche> übersetzen will.
Ich habe mit dem Englischen als "lingua franca" der modernen
Technik meinen Frieden gemacht. Das ist nicht mein Punkt.
> Wir reden von Klassen, Funktionen, [...]
Dazu unten mehr.
>> Die Geschichte der Informatik ist die Geschichte>> schlechter Begriffsbildungen und hirnrissiger>> Erklärungen.>> Beispiele?
Unzählige.
Wenn man als Einstieg mal bei Wikipädie "Programmierparadigma"
nachschlägt, dann findet man einen Berg von Geschwurbel vor,
der eines schlechten literaturwissenschaftlichen Seminars
würdig wäre. Das liegt aber nicht daran, dass die WP-Autoren
dumm wären, sondern daran, dass sich auch außerhalb der
Wikipädie niemand die Mühe gemacht hat, das hinterliegende
Konzept klar und deutlich herauszuarbeiten.
Und das Konzept ist: Programme beschreiben Automaten.
In der klassischen Ära (FORTRAN) beschrieb das Programm im
Wesentlichen einen großen Automaten; die Steuerstruktur
bestand aus GOTO, und die Variablen waren global.
Die strukturierte Programmierung ging auf die Kombinatorik
des Automaten los und legte Regeln zu dessen Strukturierung
fest; als Ergebnis dessen liegen (in Form der Prozeduren und
Funktionen) viele kleine kombinatorische Schaltnetzwerke mit
klar definierten Schnittstellen vor, die (durch Aufruf) zur
Laufzeit miteinander verschaltet werden können.
Der nächste (offensichtliche) Schritt ist die modulare
Programmierung; sie überträgt den Gedanken der Zerlegung in
handliche Teile von der Kombinatorik des Automaten auf die
Flipflop-Batterie und bildet, indem sie Flipflops und
Kombinatorik gemeinsam KAPSELT, erstmals echte Teilautomaten.
Die objektorientierte Programmierung geht hier insofern noch
einen Schritt weiter, als dass sie es erstmals ermöglicht,
zur Programmlaufzeit eine erst zur Laufzeit wählbare Anzahl
an Exemplaren desselben Automatentyps zu erzeugen. In dieser
Sichtweise ist weder die Vererbung noch die Kapselung eine
echte artbildende Eigenheit der OOP, sondern die Tatsache,
dass man Objekte zur Laufzeit erzeugen und vernichten kann.
Objekte als gekapselte Zusammenfassung von Daten und Code
sind also schlicht und ergreifend Automaten (die ja aus
einer Kombinatorik und einer Flipflop-Batterie bestehen),
und ein objektorientiertes Programm beschreibt ein Automaten-
netz.
Das Riesentamtam, das um die Detail der Vererbung (Mehrfach-
vererbung, Diamond-Problem) gemacht wird, ist in dieser Sicht
ein aufgebauschtes bürokratisches, verwaltungstechnisches
Problem, das man auch entsprechend behandeln sollte. OOP
geht auch ohne Vererbung -- also sind Vererbungsprobleme
keine immanenten OOP-Probleme.
Die Modellvorstellung "Programme beschreiben Automatennetze"
hat noch einen anderen Vorteil.
Als ich mich vor Jahren mit einem Kollegen, der im Gegensatz
zu mir einschlägige Vorlesungen gehört hatte, über VHDL
unterhielt, sagte dieser einen geradezu prophetischen Satz:
"Ach weisst Du, das ist im Prinzip genau wie C... nur es
passiert eben alles gleichzeitig."
Die Vorstellung "Programme beschreiben Automatennetze"
hat den großen Vorzug, dass sie von der (längst nicht
mehr gültigen) technischen Zufälligkeit einer sequenziellen
Maschine abstrahiert. Dabei gibt es zwei praktisch wichtige
Entwicklungsrichtungen:
Zum einen ist da das Multitasking, dessen Kern ja darin liegt,
das zahlreiche unabhängige ("virtuelle") Automaten auf dieselbe
Hardware abgebildet werden und gleichzeitig ohne sich zu stören
arbeiten. Extremstes Beispiel ist die SPS, die perfektes
Multitasking bietet, ohne den Begriff überhaupt zu kennen.
(Wer mal bei der Inbetriebnahme einer Rundtischmaschine mit
16 Stationen und hunderten Aktoren dabeiwar, weiss, was ich
meine. Wenn es hierbei einen "Crash" gibt, dann gibt es WIRKLICH
einen Crash.)
Zum anderen ist auch der Prozessor selbst längst keine rein
sequenzielle Maschine mehr; man hält lediglich an diesem
Programmiermodell fest, weil man noch kein besseres hat, das
für den Masseneinsatz tauglich wäre. Tatsächlich macht ein
üblicher PC-Prozessor ja vieles parallel, was im Programm
m.o.w. sequenziell beschrieben ist. Wenn man diese Gedanken-
schiene weiterfährt, landet man bei VHDL.
Zwei abschließende Gedanken zu diesem Teilast. Erstens: Mir
ist inzwischen klar, dass man Berechenbarkeit nicht nur mit
Bezug auf den Turing-Automaten als Modellmaschine erklären
kann, sondern auch über den Lambda-Kalkül. Wie die Brücke
von der Automatentheorie zum Lambda-Kalkül aussieht, ist mir
noch nicht klar. Lisp/Scheme/Tcl sind aber der Beweis dafür,
dass diese Frage praktisch relevant ist.
Zweitens: Auch die Brücke vom "Standard-Modell der Informatik"
(der Turing-Maschine, die ja sequenziell arbeitet) zur von
mir ständig zitierten Automatentheorie ist u.U. nicht auf
den ersten Blick offensichtlich. Man kann sich aber leicht
vorstellen, dass die Automaten durch boolesche Gleichungen
beschrieben werden können, welche wiederum durch die Turing-
Maschine sequenziell ausgewertet werden. Das führt auf das
interessante Thema, dass durch fehlerhafte Auswertung an sich
korrekter Gleichungen "parasitäre" Zustände entstehen, die
z.B. zu unerwünschten Blockierungen führen (Stichwort
"Warteschleifen und Nebenläufigkeit").
So. - Du schreibst oben, man spräche von Klassen, Methoden,
Elementfunktionen und so weiter.
Richtig. Um meine Kritik aggressiv zu formulieren: Die
praktischen Informatiker führen sich wie die spanischen
Eroberer oder die amerikanischen Siedler auf, die irgendwo
einfallen, alles niederbrennen, ihr eigenes Getreide säen
und sich einen feuchten Kehricht dafür interessieren, was
lange vor ihrem Einfallen dort schon an Interessantem
gewachsen ist.
Eine "Funktion" (im Sinne der Informatik) ist einfach eine
Kombinatorik (kombinatorischer Automat).
Ein "Objekt" ist ein Automat.
Eine "member function" ist eine zu einem Automaten gehörende
Kombinatorik.
Eine "Klasse" ist der Schaltplan eines (abstrakten) Automaten.
Eine "Instanz" ist ein konkretes Exemplar eines abstrakten
Automaten, das nach dem gültigen Schaltplan hergestellt wurde.
Nach meiner Wahrnehmung werden Sprachkonstrukte immer nur mit
Verweis auf die Theorie der Programmiersprachen erklärt. Das
kommt den Informatikern offenbar völlig natürlich vor, ist aber
deshalb fatal, weil die Programmiersprachen selbst auch nur ein
HILFSMITTEL sind -- sie dienen nämlich dazu, das VERHALTEN VON
AUTOMATEN zu beschreiben!
Die Informatiker sollten also diesen inzestuösen Rahmen, in
dem Sprachkonstrukte immer nur durch Begriffe aus der Theorie
der Programmiersprachen beschrieben werden, endlich mal ver-
lassen, und sich auf die viel relevantere Frage konzentrieren,
welchen neuen AUTOMATENSTRUKTUREN ich mit diesen Sprach-
konstrukten beschreiben kann, und warum das nützlich ist.
Carl D. schrieb:> Manchmal kann der Erkenntnisstand der "Pioniere" aber> nicht auf Nachzügler warten.
Es geht nicht um den Erkenntnisstand an sich, sondern
um die Unfähigkeit oder die Unlust, die unter vielen
persönlichen Mühen gewonnenen Erkenntnisse so umzuformu-
lieren, dass sie für andere leicht verständlich werden.
Edison sage, Genie sei 1% Inspiration und 99% Transpiration.
Die geniale Erkenntnis zu haben ist 1%, sie verständlich
zu formulieren und lehrbar zu machen, die restlichen 99%.
Hallo,
Possetitjel schrieb:> Die Informatiker sollten also diesen inzestuösen Rahmen, in> dem Sprachkonstrukte immer nur durch Begriffe aus der Theorie> der Programmiersprachen beschrieben werden, endlich mal ver-> lassen, und sich auf die viel relevantere Frage konzentrieren,> welchen neuen AUTOMATENSTRUKTUREN ich mit diesen Sprach-> konstrukten beschreiben kann, und warum das nützlich ist.
Du hast es perfekt zusammengefasst.
Das trifft allerdings nicht nur auf die "Programmierspracheninformatik"
zu, sondern findet sich immer mehr in anderen technischen Bereichen
wieder.
rhf
Possetitjel schrieb:
Frei nach dem Motto: ich schreibe eine lange Antwort, weil keine Zeit
hatte, mich kurz zu fassen.
> Und das Konzept ist: Programme beschreiben Automaten.
Nun, das lernen Informatiker typischerweise am ersten Tag.
> Nach meiner Wahrnehmung werden Sprachkonstrukte immer nur mit> Verweis auf die Theorie der Programmiersprachen erklärt. Das> kommt den Informatikern offenbar völlig natürlich vor, ist aber> deshalb fatal, weil die Programmiersprachen selbst auch nur ein> HILFSMITTEL sind -- sie dienen nämlich dazu, das VERHALTEN VON> AUTOMATEN zu beschreiben!
s.o.
Wilhelm M. schrieb:> Possetitjel schrieb:>> Frei nach dem Motto: ich schreibe eine lange Antwort,> weil keine Zeit hatte, mich kurz zu fassen.
Du irrst -- das IST die Kurzfassung.
Sie ist so lang geworden, weil ich den roten Faden klar
darstellen wollte.
>> Und das Konzept ist: Programme beschreiben Automaten.>> Nun, das lernen Informatiker typischerweise am ersten> Tag.
Mag wohl sein, dass sie es lernen -- aber sie begreifen
es nicht.
Sie lernen, dass es eine Korrespondenz zwischen den
Chomsky-Grammatiken und bestimmten Automatenklassen gibt.
Soweit stimmt das.
Die logische Umkehrung dieses Gedankens, dass ein Satz in
einer gegebenen Chomsky-Grammatik (vulgo: ein Programm)
dann auch genau einen bestimmten Automaten beschreiben
muss, habe ich noch NIRGENDWO gelesen. Nirgends. Das ist
den akademischen Theoretikern viel zu trivial, als dass
man es aufschreiben dürfte.
Selbstverständlich ist diese Umkehrung aus theoretischer
Sicht trivial -- sie ist aber aus praktischer Sicht
entscheidend, weil sie die Grundlage für meine anschauliche
Vorstellung ist: Ich darf mir JEDES Programm als Zusammen-
schaltung von 74HCxx-ICs vorstellen. Es ist mathematisch
beweisbar, dass diese Deutung zulässig ist!
Du hast Dich oben beklagt, dass Deine Versuche, C++ und
seine Vorteile zu popularisieren, so stark auf Ablehnung
stoßen. Ich habe versucht, die Ursache für diese Ablehnung
zu ergründen, indem ich meine eigenen Gedanken und Eindrücke
niederschreibe.
Etwas kürzer als oben würde ich so sagen:
Du zitierst (aus meiner Sicht zu Recht) die Forderung "stop
teaching C". Du wirst ihr aber nicht gerecht, denn Du lehrst
C++ genau so, wie all die furchtbaren C-Lehrbücher C lehren!
Du springst -- genau wie die Lehrbücher -- kopfüber in die
Details der Sprache, die festlegen, WIE man Sachverhalte
formuliert, statt Dich erstmal ausführlich bei dem (für Dich
entsetzlich langweiligen und trivialen) Thema aufzuhalten,
WAS man in der Sprache eigentlich FORMULIERT!
Die Antwort auf diese Frage sollte nämlich NICHT "einen
Algorithmus" lauten, sondern "einen Automaten". (Eigentlich
"ein Automatennetz". Egal.) Das ist nämlich MEINER Meinung
nach das Wesentliche am Programmieren.
So. Jetzt gibt es das andere Problem: Wer C gelernt hat, bei
dem ist das Kind schon in den Brunnen gefallen, denn der hat
bereits verinnerlicht, dass man in einer Programmiersprache
"selbstverständlich" einen Algorithmus formuliert, also eine
Vorschrift, die nach endlich vielen Schritten zum Ergebnis
führt. Die (theoretisch zweitrangige) Prämisse der sequenziellen
Verarbeitung ist unauslöschlich in sein Hirn eingebrannt. Man
müsste also aus dieser Sackgasse erstmal rückwärts herausfahren
und den Gedanken popularisieren, dass man auch in klassischem
C das Verhalten von AUTOMATEN beschreibt, denn dann hat man
konkrete Anknüpfungspunkte für die Demonstration, wieso man
dieses und jenes in C++ BESSER als in C beschreiben kann.
Überspitzt ausgedrückt: Man muss auch beim Lehren von C die
Prämisse "stop teaching C" beherzigen!
Oder das Ganze NOCH kürzer:
Vieles, was über Programmierung gesagt wird, suggeriert, das
Programm beschriebe direkt die Sachverhalte der Anwendungs-
domäne.
Das ist Schwachsinn. Der Programmierer bildet die Sachverhalte
der Anwendungsdomäne in einen abstrakten Automaten ab, und
DIESER AUTOMAT wird mit den Mitteln der Programmiersprache
beschrieben. Die Gesamtabbildung ist nicht einstufig, sondern
zweistufig.
Nur diese Tatsache macht es möglich, unterschiedliche
Programmiersprachen einigermaßen effizient miteinander zu
vergleichen.
Possetitjel schrieb:> Ich darf mir JEDES Programm als Zusammen-> schaltung von 74HCxx-ICs vorstellen. Es ist mathematisch> beweisbar, dass diese Deutung zulässig ist!
Als Automaten-Theorie, Turing-Maschine oder gar Lambda-Kalkül erfunden
wurden, gab es noch gar keine 74er-IC's, oder überhaupt irgendwelche
Halbleiter. Tatsächlich hat die Informatik mit völlig abstrakten
Beschreibungen von mathematischen Algorithmen angefangen, als es
nichtmal Röhren gab. Die Informatiker haben hier also definitiv nicht
wie Conquistadores die schönen Konstruktionen der Ingenieure
durcheinander gebracht. Vor allem der Lambda-Kalkül ist komplett
losgelöst von Dingen wie "Zustände" (Flipflops) und sequentieller
Ausführung, auch wenn er bijektiv auf Turing-Maschinen abbildbar ist.
Ausgehend von dieser theoretischen Basis wurden Programmiersprachen,
Parser und auch heutige Bestandteile der Informatik entwickelt. Ob die
jetzt auf Papier&Stift, Mechanische Rechner, Röhren-Rechner, 74er-Gräber
oder integrierte CPU's ausgeführt werden ist komplett egal.
Viele der Begriffe wie "Klasse" oder "Funktion" kommen aus der
Mathematik (Informatik = Informations-Mathematik), und klingen daher
Un-Ingenieurisch, aber sind sie deswegen falsch?
Unbestritten ist in der Mathematik "f(x)=7*x" eine Funktion. In C wäre
das dann z.B.
1
doublef(doublex){return7.*x;}
Soll man das jetzt nicht mehr Funktion nennen? Soll man es Automaten
nennen obwohl es überhaupt keinen Zustand ("Flipflops") hat?
Auch wenn es richtig ist dass prinzipiell jedes Programm einen Automaten
beschreibt, braucht man dennoch höhere Abstraktionen, ja, Bürokratie, um
der Komplexität Herr zu werden. Daher gibt es Datenstrukturen, welche
Daten (und Daten sind ja das, um das sich alles dreht) als Black Boxen
kapseln. Dafür ist OOP, inklusive Dingen wie Vererbung, ein
erwiesenermaßen äußerst nützliches Hilfsmittel. Dinge wie Interfaces
scheinen nutzlose Bürokratie zu sein; genau wie der Dienstweg in
komplexen Organisationen. Aber ohne versinkt schnell alles im Chaos. OOP
geht auch in C und wird auch gemacht, z.B. im Linux-Kernel.
Würdest du auch Programme in rein funktionalen Sprachen als Automaten
bezeichnen? Diese enthalten keine Anweisungen, beschreiben keinen
Zustand, verändern keine Daten, lassen sich nur nichttrivial auf
tatsächliche Rechner umsetzen, die wie "Automaten" aufgebaut sind. Sie
bieten nur ein Mapping Eingabe->Ausgabe. Dennoch kann man alles damit
berechnen.
Es ist übrigens sehr lehrreich mal 1-2 Module theoretische Informatik zu
besuchen; dort werden die mathematischen Wurzeln der Informatik offenbar
und warum die Informatik sich eben nicht als Hilfswissenschaft für
Ingenieure sieht.
Außerdem finde ich dass die Ingenieurs-Wissenschaften auch nicht
besonders zugänglich sind. Unmengen an kaputt-missbrauchter Mathematik
und ebenso abgehobenen Begriffen machen die auch nicht leichter
verständlich.
Überhaupt ist es spannend, wie hier (vermutlich) Ingenieure immer wieder
erklären wie sie alles besser wissen als Informatiker. Machen andere
Fachbereiche so etwas auch? Haben solche Ingenieure überhaupt genügend
Informatik-Wissen um darüber urteilen zu können?
Jetzt trete ich mal (wie schon so oft) kräftig ins Fettnäpfchen:
Ich lese ja gerne mit und nichts liegt mir ferner als "Religion" zu
machen. Von meiner begrenzten Vista kann ich nur kommentieren, daß die
moderne Sprachenevolution höchstwahrscheinlich ihre Berechtigung und
Grund hat um komplizierte (moderne) Probleme besser lösen zu können.
Ich sehe es an mir, bei den C++ Beispielen blicke ich ohne weitgehende
Recherche nicht mehr durch. Mein Gehirn ist total auf das klassische
Programmieren eingerastet. Klassische Sprachen verstehe ich. Ich muß
alles verstehen und komplett sehen können. Bei Klassischen C u.ä. tut
man sich da leicht. Wenn ich mir aber das neueste C++ ansehe kann ich
die klare Logik nicht mehr verfolgen. Sorry. Es geht einfach nicht. Das
ist mir dann zu abstrakt und versteckt. C++ auf Niveau z.B vieler
Arduino Bibliotheken kann ich noch einigermaßen verstehen. Die neuesten
Konzepte sind mir aber im Augenblick einfach noch zu abstrakt.
Da bei mir der Schwerpunkt meines Interesses auf uC liegt, komme ich
praktisch mit C sehr gut zurecht. Hier schwimme ich in meinem
natürlichen Element. Mit C++ bin ich zur Zeit noch aus meinem Element
heraus.
Was ich damit sagen will ist, daß wahrscheinlich nur Leute mit den neuen
Konzepten wirklich glücklich werden die noch nicht mit klassischen
Programmieren vorbelastet sind. Wer also mit C++ und Objekt Konzepten
groß wird für den ist das höchstwahrscheinlich intuitiv. Klassisches
Programmierverständnis hindert hier massiv. Wer so wie ich mit
klassischen Programmieren groß geworden ist, tut sich oft schwer so weit
umzudenken. Auch wenn ich mir Mühe gebe, AHA Momente sind leider nur
spärlich. Tut mir leid, es ist aber so.
Dann kommt noch dazu, daß man viel neuen Syntax und Konzepte lernen muß
und sehr viel Zeit mit Studium der neuen Sprachen verbringen muß. Auch
kenne ich niemand in meinem Umfeld der zusammen mit mir mal ein kleines
praktisches Lehrprojekt machen würden.
Wenn es möglicherweise anderen ähnlich wie mir geht, dann müßte man
daraus schließen, daß wenn dazu lernen nicht wirklich funktioniert man
eben das akzeptieren sollte und mit den Methoden die man beherrscht die
anfallenden Probleme lösen sollte. Ich fürchte, auch wenn ich mir sehr
viel Mühe gebe würde, daß der Groschen einfach nicht bald genug fallen
würde.
Nicht jeder muß für eine Firma arbeiten, die darauf besteht, daß man die
gängigen Sprachen beherrscht um kommerziell damit arbeiten zu können.
Deshalb finde ich es besser mit dem Missionarisieren hier im Forum gar
nicht erst anzufangen und sich gegenseitig zu respektieren. Ich finde
jedenfalls die vorgestellten Beispiele durchaus interessant und plane
mich auch etwas damit zu befassen sobald meine Tool Chain funktioniert.
Aber meine eigenen Projekte ziehe ich lieber so durch wie ich es eben
gelernt habe.
So ihr seht, bei mir ist, wie man sagt, Hopfen und Malz verloren:-)
Also, macht weiter. Interessieren tut es mich schon was auf dem Gebiet
der C++ Entwicklung so gemacht wird und zeigt wie man Probleme
heutzutage löst.
Ich hoffe ich habe mich hier mit meinem Kommentar nicht zu sehr
blamiert. Aber ich wollte nur mal berichten wie es von der anderen Seite
des Zauns aussieht...
Schönen Tag noch,
Gerhard
Das beschreibt ziemlich eindeutig einen Automaten. Es werden
nacheinander Daten-manipulierende Befehle abgearbeitet. In C++ und
vielen anderen Sprachen sieht das so aus:
Hier sieht man nicht mehr viel vom Automaten auch wenn die Hardware
letztendlich einer ist. Ist es hier nicht viel sinnvoller in Form von
Funktionen und Datenstrukturen zu denken? Die string-Klasse kapselt
Daten, die greeting-Funktion bildet Daten auf andere Daten ab. Das auf
Logik-IC's umzusetzen erfordert schon ziemliche Hirn-Verrenkungen, die
hier nicht besonders nützlich sind.
Übrigens nutzt auch std::string die böse template-Metaprogrammierung,
aber als Nutzer sieht man davon nichts.
Gerhard O. schrieb:> Wer also mit C++ und Objekt Konzepten> groß wird für den ist das höchstwahrscheinlich intuitiv.
OOP stammt aus den 60ern/70ern, und C++ aus den 80ern... Wann hast du
denn programmieren gelernt?
Dr. Sommer schrieb:> Gerhard O. schrieb:>> Wer also mit C++ und Objekt Konzepten>> groß wird für den ist das höchstwahrscheinlich intuitiv.>> OOP stammt aus den 60ern/70ern, und C++ aus den 80ern... Wann hast du> denn programmieren gelernt?
In den 80er Jahren. Motorola 6800 ASM, HP-BASIC/QB45/7, viel
Instrumentsteuerung mit HP-IB, 8051 Assembler, Delphi., C. LabVIEW.
Also alles Zeugs um man sich heutzutage nicht mehr viel schert. Altes
Eisen...
Auch wenn, wie Du sagst die Grundlagen "modern" implementierter Konzepte
teils schon betagt sind, bin ich damit nie konfrontiert worden. Formell
habe ich mich also mit den heutigen Mainstream Werkzeugen nie damit
befaßt. Machte also nur HW und embedded Sachen. Man bleibt eben oft
lieber auf dem familiären Pfad. Für mich sind das eben die erwähnten
Werkzeuge. Sachen wie Lambda Kalkül sind für mich leider ein Fremdwort.
Abgesehen davon habe ich mich damals hauptsächlich mit diskreten Logik
Design befasst und viel Analog und Funktechnik. Programmieren war nur
Mittel zum Zweck um Mikroprozessor/uC einsetzen zu können. Und das
machte man damals eben mit ASM und C. Es bestand nie eine Notwendigkeit
viel über den Tellerrand zu schauen weil die Werkzeuge die man kannte
eben ausreichend waren um die anfallenden Probleme zu bewältigen. Man
könnte auch dazu sagen, man stagnierte:-)
Na, dann bist du auch ein bisschen selber schuld die "modernen"
Techniken nicht zu kennen :-)
Das Lambda-Kalkül ist eine der ersten Programmiersprachen, praktisch der
Prototyp aller funktionalen Sprachen, aus den 30er-Jahren. Sie hat keine
praktische Bedeutung, ist aber theoretische Grundlage für viele wichtige
Konzepte. Spannend daran ist dass die Sprache extrem simpel ist und noch
nicht einmal Zahlen kennt, man damit aber dennoch alles berechnen kann
(ist äquivalent zur Turing-Maschine) - "rechnen mit nichts".
Dr. Sommer schrieb:> Hier noch ein Beispiel, eine einfache String-Konkatenation welche auch> 0-Bytes können soll. In C:
Also auf jeden Fall eleganter und "Powerful" sieht das zweite Beispiel
schon aus. Nur verstehe ich im Augenblick nicht wie es unter der Haube
funktioniert. Da müßte man schon mit der String Library vertraut sein.
Da scheint der Compiler die notwendige Funktionalität des Ausdruckes
anhand des Syntax selber zu konstruieren anstatt eine traditionelle C
String Funktion wählen zu müssen. Sehe ich das richtig oder rede ich
hier Stuss?
Aber es illustriert wie man sich auf die Anwendung beschränken kann und
sich nicht mit Implementierungsdetails verzetteln muß.
Gibt es Version vom GCC mit dem das auc auf uC funktionieren würde?
Wilhelm warf ein, daß teilweise das nur auf größeren Systemen anwendbar
ist und auf AVR es im Augenblick anscheinend noch nicht verfügbar ist.
Dr. Sommer schrieb:> Na, dann bist du auch ein bisschen selber schuld die "modernen"> Techniken nicht zu kennen :-)> Das Lambda-Kalkül ist eine der ersten Programmiersprachen, praktisch der> Prototyp aller funktionalen Sprachen, aus den 30er-Jahren. Sie hat keine> praktische Bedeutung, ist aber theoretische Grundlage für viele wichtige> Konzepte. Spannend daran ist dass die Sprache extrem simpel ist und noch> nicht einmal Zahlen kennt, man damit aber dennoch alles berechnen kann> (ist äquivalent zur Turing-Maschine) - "rechnen mit nichts".
Ich habe mir das Wiki dazu durchgelesen. Leider verstehe ich von der
Unterliegenden Mathe zum Teil nur Bahnhof. Das ist mir zu theoretisch.
Gerhard O. schrieb:> Nur verstehe ich im Augenblick nicht wie es unter der Haube> funktioniert.
Die Idee ist, dass man das auch nicht muss. Wenn man komplexe Systeme
hat kann man unmöglich jede Komponente begreifen...
Gerhard O. schrieb:> Da scheint der Compiler die notwendige Funktionalität des Ausdruckes> anhand des Syntax selber zu konstruieren
Gewissermaßen... Die string-Klasse definiert einen eigenen "+"-Operator
welcher alles Notwendige erledigt. Ist im Endeffekt eine Funktion mit
komischem Namen, die hier aufgerufen wird.
Gerhard O. schrieb:> Gibt es Version vom GCC mit dem das auc auf uC funktionieren würde?
Leider nicht. Die string-Klasse benötigt dynamischen Speicher, der auf
kleinen AVR's problematisch ist. Man könnte sich etwas basteln (mit mehr
templates...) was dort einsetzbar ist aber dann natürlich eingeschränkte
Funktionalität hat. Vielleicht würde es reichen einen eigenen Allokator
zu übergeben, ich hab das noch nicht versucht...
Gerhard O. schrieb:> Ich habe mir das Wiki dazu durchgelesen. Leider verstehe ich von der> Unterliegenden Mathe zum Teil nur Bahnhof. Das ist mir zu theoretisch.
Ja, für praktische Anwendung bringt das eh nichts. Wenn du mit
funktionaler Programmierung anfangen möchtest kannst du dir Sprachen wie
Lisp, Scala, Haskell, ... anschauen.
Dr. Sommer schrieb:> Possetitjel schrieb:>> Ich darf mir JEDES Programm als Zusammen->> schaltung von 74HCxx-ICs vorstellen. Es ist mathematisch>> beweisbar, dass diese Deutung zulässig ist!>> Als Automaten-Theorie, Turing-Maschine oder gar Lambda-Kalkül> erfunden wurden, gab es noch gar keine 74er-IC's,
Das war auch nicht meine Aussage.
> oder überhaupt irgendwelche Halbleiter.
Ich kenne durchaus Namen wie Zuse oder Babbage, und ich kenne
auch die Geschichten rund um die Enigma. Ach so... "Dreloba"
sagt Dir etwas?!
> Die Informatiker haben hier also definitiv nicht wie> Conquistadores die schönen Konstruktionen der Ingenieure> durcheinander gebracht.
Du missverstehst mich. Die "praktischen Informatiker"
haben das Land der Mathematiker und Logiker verwüstet.
Was ich oben über Programmierparadigmen schrieb, habe ich
mir ja zum größten Teil nicht selbst ausgedacht, sondern
mir nur mit unendlicher Mühe aus einigen wenigen sehr guten
Theoriebüchern zusammengeklaubt: Logik, Compilerbau, theo-
retische Informatik.
Die echt harte Arbeit bestand darin, die sehr nützlichen
theoretischen Begriffe in die Praxis rückzuübertragen.
In den Büchern über Programmierung und Programmiersprachen
findet man davon nämlich nix. Die verzetteln sich in den
sprachlichen Einzelheiten, die die Konzepte mehr verdecken
als erklären.
> Vor allem der Lambda-Kalkül ist komplett losgelöst von> Dingen wie "Zustände" (Flipflops) und sequentieller> Ausführung, [...]
GENAU DAS schrieb ich (in etwas anderen Worten) in meinem
ersten Beitrag.
> Viele der Begriffe wie "Klasse" oder "Funktion" kommen> aus der Mathematik (Informatik = Informations-Mathematik),> und klingen daher Un-Ingenieurisch, aber sind sie deswegen> falsch?
Nein -- nicht deswegen.
Sie sind deswegen furchtbar, weil die praktischen Informatiker
die Mathematik so verhuntzen. Korrigiere mich, wenn ich falsch
liege, aber eine C-function, die eine static-Variable enthält,
ist doch genau KEINE zustandsfreie Funktion mehr, oder?
> Unbestritten ist in der Mathematik "f(x)=7*x" eine Funktion.> In C wäre das dann z.B.double f (double x) { return 7. * x; }> Soll man das jetzt nicht mehr Funktion nennen?
Kommt auf den Kontext an.
> Soll man es Automaten nennen obwohl es überhaupt keinen> Zustand ("Flipflops") hat?
Das wäre durchaus ein sinnvoller Anfang. Wenn man weiter
vorn erklärt hat, was Automaten sind, ist die Auffassung
einer reinen Kombinatorik als Grenzfall eines Automaten
("entarteter Automat") sinnvoll, ja. Genauso ist ja die
Auffassung eines reinen Flipflops als Automaten ohne
weitere Kombinatorik sinnvoll.
> Auch wenn es richtig ist dass prinzipiell jedes Programm> einen Automaten beschreibt, braucht man dennoch höhere> Abstraktionen, [...]
Selbstverständlich. Dagegen habe ich nichts.
Ich habe überhaupt nichts gegen höhere Abstraktion, wenn
zuvor die einfachen, leicht zugänglichen Modelle und
Vorstellungen erklärt würden.
> Würdest du auch Programme in rein funktionalen Sprachen> als Automaten bezeichnen?
Nein -- es SIND keine Automaten, aber sie beschreiben das
VERHALTEN von Automaten. Genau DAS wird ja durch die
bijektive Abbildbarkeit auf die Turing-Maschine garantiert!
Und genau DESWEGEN ist die Vorstellung mit den Automaten
so genial: Sie klappt auch, wenn "in Wahrheit" gar keine
Automaten da sind!
> Es ist übrigens sehr lehrreich mal 1-2 Module theoretische> Informatik zu besuchen; dort werden die mathematischen> Wurzeln der Informatik offenbar und warum die Informatik> sich eben nicht als Hilfswissenschaft für Ingenieure sieht.
Mir ist relativ egal, wie sich die Informatiker selbst sehen.
Die theoretische Informatik steht sicher der Logik und der
Mathematik näher als den Ingenieurswissenschaften -- ganz
wie das auch in der theoretischen Elektrotechnik ist.
Die praktische oder angewandte Informatik IST für mich eine
Ingenieursdisziplin, genauso wie die Elektrotechnik.
> Außerdem finde ich dass die Ingenieurs-Wissenschaften auch> nicht besonders zugänglich sind. Unmengen an kaputt-> missbrauchter Mathematik und ebenso abgehobenen Begriffen> machen die auch nicht leichter verständlich.
Mag sein... da bin ich sicher nicht der optimale Gesprächs-
partner; was die Elektrotechnik angeht, bin ich naturgemäß
sehr voreingenommen.
In einem gebe ich Dir aber Recht: Gute Dozenten sind rar,
und wirklich gute Lehrbücher auch. Die Suche wird nur etwas
vereinfacht, weil die Disziplinen schon etwas älter sind als
die Informatik, und sich die Spreu schon mehr vom Weizen
getrennt hat.
> Überhaupt ist es spannend, wie hier (vermutlich) Ingenieure> immer wieder erklären wie sie alles besser wissen als> Informatiker.
Du missverstehst mich.
Ich weiss keineswegs ALLES besser als die Informatiker. Mein
Zielpunkt ist nur genau eine Sache, nämlich die didaktisch
geschickte VERMITTLUNG gewisser Teile der angewandten
Informatik.
Eingefleischte Informatiker müssen damit notwendigerweise
Probleme haben -- sie haben nämlich die Scheuklappen auf, die
ICH als Elektrotechniker in der E-Technik habe. Mir war auch
lange Zeit schleierhaft, wie man den Unterschied von Strom
und Spannung nicht kennen kann, aber ich musste mich darauf
einstellen, dass es sehr vielen Laien so geht. Arroganz hilft
da nicht weiter.
> Haben solche Ingenieure überhaupt genügend Informatik-Wissen> um darüber urteilen zu können?
Sagen wir es mal so: Da Du oben auffällig viele Sätze mit "Zwar
ist richtig, dass..." eingeleitet hast, kann die sachliche
Substanz dessen, was ich schrieb, SOOO verkehrt gar nicht
gewesen sein.
Ich stelle ja keine Behauptungen über den sachlichen Kern
der Informatik auf. Meine Aussage ist nur: Die übliche Form
der Lehre, der Darstellung lehrt meiner Meinung nach die
Dinge in einer ungünstigen Reihenfolge und mit falschen
Prioritäten.
Das ist in der Mathematik ganz genauso: Das, was als theo-
retisches Fundament der Mathematik angesehen wird, lernt man
KEINESWEGS in der 1. Klasse. Dort lernt man mathematische
Trivialitäten wie das Zahlenrechnen.
Die Grundlagen der Mathematik lernt eine winzige Minderheit
der Menschen -- nämlich im Mathematikstudium.
Jetzt ist mir noch eine Perspektive zum Thema eingefallen die vielleicht
erklärt warum es vielen möglicherweise so wie mir geht.
Konzepte wie z.B Lambda Kalkül scheint mehr ein Hochschulthema zu sein
wie frühere angewandte Problemlösung.
Wer ab den 70er Jahren mit Mikro/uC Projekten arbeiten mußte,
konzentrierte sich hauptsächlich mit den praktischen Problemen der HW/FW
Implementierung. Man dachte hauptsächlich in Logik Terminologie und
Algorithmen der Anwendung. Ich glaube nicht, daß die damaligen
Ingenieure sich viel mit Informatik Theorie befaßt haben oder mußten.
Alles drehte sich nur darum die HW zum Laufen zu bringen. Z.B ein
Entwicklungsteam bei R&S konzentrierte sich damals eben das Meßgerät
funktionsfähig zu machen.
Viele heutige Anwendungen die hauptsächlich mit Daten arbeiten, also
dort wo die unterliegende HW nur noch Mittel zum Zweck ist, dort scheint
die theoretische Informatik viel wichtiger geworden zu sein. Das sieht
man ja im gesammten Internetanwendungsbreich und Frontier Sachen wie
K.I.
Die Natur der Projekte hat sich also seit den 1970ern gewaltig geändert
und eine gewisse Perspektive ist bitter notwendig. Auch wenn
Maschinensteuerung immer noch aktuell ist, hat sich deren Verwirklichung
total gewandelt. Deshalb sehe ich auch ein, daß die modernen Anwendungen
andere Werkzeuge benötigen die eben mit den Anwendungen gewachsen sind
oder müssen.
OK. Muß jetzt weg
Gerhard
Dr. Sommer schrieb:> Wenn du mit funktionaler Programmierung anfangen> möchtest kannst du dir Sprachen wie Lisp, Scala,> Haskell, ... anschauen.
Frage am Rande: Aufgrund welcher Verschwörung fehlt
Tcl regelmäßig in solchen Aufzählungen?
(Die Frage ist völlig ernst gemeint; ich weiss viel zu
wenig von funktionaler Programmierung, um einen fundierten
Vergleich zwischen Tcl und Lisp anstellen zu könnnen.)
Possetitjel schrieb:> Sie sind deswegen furchtbar, weil die praktischen Informatiker> die Mathematik so verhuntzen. Korrigiere mich, wenn ich falsch> liege, aber eine C-function, die eine static-Variable enthält,> ist doch genau KEINE zustandsfreie Funktion mehr, oder?
Logisch. Der Begriff wird beibehalten. Es wird daher auch teilweise nach
"Prozedur" umbenannt. Funktionslokale statische nicht-konstante
Variablen sind auch so ein typisches C-Unding.
Possetitjel schrieb:> Ich habe überhaupt nichts gegen höhere Abstraktion, wenn> zuvor die einfachen, leicht zugänglichen Modelle und> Vorstellungen erklärt würden.
Ich finde OOP sehr intuitiv und verständlich. Kurioserweise haben
meistens die E-Techniker Probleme damit, obwohl da eigentlich noch mehr
in Komponenten und Black-Boxes gedacht wird (IC's, Platinen, Baugruppen,
...).
Possetitjel schrieb:> Die praktische oder angewandte Informatik IST für mich eine> Ingenieursdisziplin, genauso wie die Elektrotechnik.
Für andere aber nicht. Ich merke deutlich die Unterschiede im Denken bei
der Zusammenarbeit mit Ingenieuren.
Possetitjel schrieb:> Die übliche Form> der Lehre, der Darstellung lehrt meiner Meinung nach die> Dinge in einer ungünstigen Reihenfolge und mit falschen> Prioritäten.
Jeder lernt anders. Ich hätte mir auch eine andere Lehre gewünscht, aber
auch nicht so wie du sie dir vorstellst. Man kann es nicht jedem Recht
machen. Die sehr praktische Herangehensweise generiert schnelle
Erfolgserlebnisse, was vielen beim Lernen hilft. Auch ein Grund warum
z.B. Python viel besser für die Lehre geeignet ist als C...
Dass Theorie und Praxis weit auseinander liegen ist der typischen
akademischen Organisation geschuldet. Und das ist in der E-Technik
genauso - welcher E-Technik-Student kann einen Blinker mit NE555 bauen?
Possetitjel schrieb:> Dort lernt man mathematische> Trivialitäten wie das Zahlenrechnen.
Das ist auch das was 95% der Leute in ihrem Leben brauchen. Leider wird
Mathe immer noch als uncool angesehen, es gilt schon als chic zu sagen
"Mathe konnte ich nie". Bei Sprachen-Fächern sagt das keiner...
Wenn du in der 1. Klasse mit Definition der natürlichen, ganzen,
rationalen, irrationalen Zahlen und Körpern anfängst und dann beweist
dass R einer ist, hilft das absolut niemandem.