Cman schrieb:> und warum ist das undefined?
Na fragen wir doch mal anders: Welchen Sinn hätte die Operation denn?
Mir fiele auch nach längerem Nachdenken keine Anwendung ein, bei der man
z.b. erst eine Variable um 1 erhöht, eine Modulo-Operation darauf
anwendet und das Ergebnis dann in die selbe Variable zurückschreibt. Ich
mein, ich fände das mal interessant wo so etwas sinnvoll sein soll.
Klingt für mich zunächst mal für einen ungünstigen Algorithmus der
Optimierungspotential beinhaltet.
Cman schrieb:> und warum ist das undefined?
Weil das = kein Sequence Point ist. D.h., es ist unklar, ob das ++ vor
oder nach der Zuweisung kommen müsste. Und so unklar, dass dabei alles
schief gehen kann und der Compiler 100 Zeilen vorher 7 Bytes im opcode
drehen darf. Oder WW3 auslösen.
Cman schrieb:> und warum ist das undefined?
Man darf zwischen zwei Sequenzpunkten eine Variable nicht mehrmals
beschreiben. Sie wird hier aber einmal durch das = und einmal durch das
++ geschrieben. Der einzige Sequenzpunkt dieser Zeile ist bei dem
Semikolon am Ende.
M. K. schrieb:> Cman schrieb:>> und warum ist das undefined?>> Na fragen wir doch mal anders: Welchen Sinn hätte die Operation denn?> Mir fiele auch nach längerem Nachdenken keine Anwendung ein, bei der man> z.b. erst eine Variable um 1 erhöht, eine Modulo-Operation darauf> anwendet und das Ergebnis dann in die selbe Variable zurückschreibt. Ich> mein, ich fände das mal interessant wo so etwas sinnvoll sein soll.> Klingt für mich zunächst mal für einen ungünstigen Algorithmus der> Optimierungspotential beinhaltet.
Wenn du einen Wert hast mit dem Typen uint8_t und du willst zB für eine
Uhr nur von 0 bis 59 zählen?
Rolf M. schrieb:> Cman schrieb:>> und warum ist das undefined?>> Man darf zwischen zwei Sequenzpunkten eine Variable nicht mehrmals> beschreiben. Sie wird hier aber einmal durch das = und einmal durch das> ++ geschrieben. Der einzige Sequenzpunkt dieser Zeile ist bei dem> Semikolon am Ende.
Danke ;)
Jörg W. schrieb:> counter = (counter + 1) % 10;> ist vermutlich zu einfach zu schreiben. :-))
Danke ;)
Kaj schrieb:> Diese ganze Sache hatten wir doch aber gerade schon mal...> Beitrag "Dekrementieren vs. Subtrahieren (n-- vs n-1)"
Danke ;)
Cman schrieb:> Wenn du einen Wert hast mit dem Typen uint8_t und du willst zB für eine> Uhr nur von 0 bis 59 zählen?
Das ist doch trotzdem kein Grund, auf die gleiche Variable innerhalb der
Operation zweimal einen Wert zuweisen zu wollen (und noch dazu nicht
den gleichen).
Du vergisst, dass die Eingangszeile eine Kurzform ist von
Achim S. schrieb:> If(++counter > 59) {counter = 0;}
Das funktioniert nur, wenn man immer, und für alle Zeiten, GARANTIEREN
kann, dass counter nicht woanders verändert wird.
> counter = (counter + 1) % 60;
Ist im dem Punkt erheblich robuster
Arduino Fanboy D. schrieb:> Ist im dem Punkt erheblich robuster
Und je nach Plattform erheblich langsamer.
Arduino Fanboy D. schrieb:> GARANTIEREN kann, dass counter nicht woanders verändert wird.
Dazu kapselt man ihn in eine Klasse die keine anderen Schreibzugriffe
zulässt.
Arduino Fanboy D. schrieb:> Achim S. schrieb:>> If(++counter > 59) {counter = 0;}>> Das funktioniert nur, wenn man immer, und für alle Zeiten, GARANTIEREN> kann, dass counter nicht woanders verändert wird.>>> counter = (counter + 1) % 60;> Ist im dem Punkt erheblich robuster
Wenn man das unbedingt braucht kann man aber auch einfach schreiben:
1
if(++counter>59){counter-=60;}
Dann passiert genau das selbe wie bei der Modulo-Operation, solange der
Wert nicht zwischen zwei Aufrufen dieses Codes mehr als einmal
überläuft. Sollte das der Fall sein, würde auch nocht gehen:
1
++counter;
2
while(counter>59){counter-=60;}
Ich schreibe in so einem Fall die Inkrememntierung eh normalerweise in
eine eigene Zeile.
Jörg W. schrieb:> counter = (counter + 1) % 10;
Auf MCs ohne HW-Division muß dazu aber die Math-Lib aufgerufen werden,
d.h. es kann dauern und das jedesmal. Effizienter ist daher ein
Vergleich.
Da diese Aufgabe recht oft auftritt, habe ich mir dafür ein Macro
geschrieben:
1
#define ROLLOVER( x, max ) x = ++x >= max ? 0 : x
Man beachte, x läuft von 0 bis max-1.
Der Ternary Operator ist ein Sequence Point, d.h. ++x wird zuerst
ausgeführt.
Dr. Sommer schrieb:> Profis™ machen das so:
Aber Du weißt doch, dass Du in diesem Forum eine C Frage nicht mit C++
beantworten darfst!!!
Zumindest hatte ich oben noch den Hinweis dazu geschrieben, dass C das
nicht kann :-)
Cman schrieb:> Wenn du einen Wert hast mit dem Typen uint8_t und du willst zB für eine> Uhr nur von 0 bis 59 zählen?
Hm, das hätte ich auch mit einer if-Bedingung gelöst aber ok, das wäre
in der Tat eine Anwendungsmöglichkeit.
Dr. Sommer schrieb:> Profis™ machen das so:> Keine Division, keine Möglichkeit einen zu hohen Wert zuzuweisen.
Beim CTor wäre ich vorsichtig, eine Assertion wäre sinnvoll.
Dr. Sommer schrieb:> Sonst kommt die C-Polizei!
Das nicht, aber ein Großteil der Leser wird damit nichts anfangen
können.
Du hättest Deinen Beitrag genauso gut in chinesisch posten können.
Peter D. schrieb:> Auf MCs ohne HW-Division muß dazu aber die Math-Lib aufgerufen werden,
Das ist sogar auf einigen der großen ARM Cortex-A so. Die haben
ebenfalls keine Hardware-Division (da man Division so selten braucht,
ist es sinnvoller die Chipfläche für mehr Cache, Branch-Prediction usw.
zu nutzen). Da ARM aber generell sehr effizient kurze bedingte Blöcke
ausführen kann (Conditional Execution) ist die Variante mit "if" auf dem
Cortex-A erst recht deutlich schneller. Das wird dann zu:
1
add r0, #1
2
cmp r0, #10
3
movhs r0, #0
Ist der Modulo-Divisor allerdings einer 2er-Potenz (z.B. 8), wird der
Compiler das "%" zu einem "And" optimieren, was dann noch schneller als
das "if" sein sollte (auch auf ARM):
1
add r0, #1
2
and r0, #0x7
Peter D. schrieb:> Das nicht, aber ein Großteil der Leser wird damit nichts anfangen> können.
Vielleicht denkt man sich dann, dass es vielleicht doch keine schlechte
Idee ist mal über den C-Horizont hinaus zu blicken.
Peter D. schrieb:> Dr. Sommer schrieb:>> Sonst kommt die C-Polizei!>> Das nicht, aber ein Großteil der Leser wird damit nichts anfangen> können.
Die C-Polizei lauert hinter jeder Ecke ...
> Du hättest Deinen Beitrag genauso gut in chinesisch posten können.
Ja, das stimmt. Denn die sind Verbesserungen gegenüber sehr
aufgeschlossen!
Arduino Fanboy D. schrieb:> Achim S. schrieb:>> If(++counter > 59) {counter = 0;}>> Das funktioniert nur, wenn man immer, und für alle Zeiten, GARANTIEREN> kann, dass counter nicht woanders verändert wird.
Das ist jetzt aber ein Allgemeinplatz imho ...
Das meiste funktioniert nur, wenn es nicht woanders verändert wird ;-)
Mampf F. schrieb:> Das meiste funktioniert nur, wenn es nicht woanders verändert wird ;-)
Ein "counter = 72;" ist schnell mal versehentlich getippt. Ein
"reinterpret_cast<std::uint8_t&> (counter3) = 72;" zur Umgehung des
Zugriffsschutzes nicht so sehr.
Dr. Sommer schrieb:> Mampf F. schrieb:>> Das meiste funktioniert nur, wenn es nicht woanders verändert wird ;-)>> Ein "counter = 72;" ist schnell mal versehentlich getippt. Ein> "reinterpret_cast<std::uint8_t&> (counter3) = 72;" zur Umgehung des> Zugriffsschutzes nicht so sehr.
Ja, man sollte schon wissen, was man macht ;-)
Passiert selten, dass ich irgendetwas tippe, was ich nicht möchte - im
Rausch eventuell, aber wenn man wieder nüchtern ist, klärt sich das
meistens.
Mampf F. schrieb:> Passiert selten, dass ich irgendetwas tippe, was ich nicht möchte
Normal-Intelligenten Programmierern wie mir passiert es leider öfter
mal, dass man versehentlich was falsches tippt. Das ist der Sinn von
Sprachen mit Zugriffsschutz (fast alle außer C) und anderen Mechanismen
mit dem selben Ziel (insb. Typsicherheit) - man wird vor der eigenen
Unachtsamkeit geschützt, man muss schon mit Absicht diese Mechanismen
umgehen.
Arduino Fanboy D. schrieb:> Achim S. schrieb:>> If(++counter > 59) {counter = 0;}>> Das funktioniert nur, wenn man immer, und für alle Zeiten, GARANTIEREN> kann, dass counter nicht woanders verändert wird.>>> counter = (counter + 1) % 60;> Ist im dem Punkt erheblich robuster
Warum soll das robuster sein?
Wenn durch einen Programmierfehler ein Wert außerhalb des erlaubten
Bereiches zugewiesen wurde, ist es herzlich egal, was nun der nächste
Wert ist. Die Uhr, die FIFO, der gleitende Mittelwert usw. machen in
beiden Fällen Mumpitz.
Arduino Fanboy D. schrieb:>> If(++counter > 59) {counter = 0;}>> Das funktioniert nur, wenn man immer, und für alle Zeiten, GARANTIEREN> kann, dass counter nicht woanders verändert wird.
Wenn meine Funktion oben nicht funktioniert, dann must Du definieren,
welche Arten von Fehlern oder Anwendungsfällen Du zulässt, und zu
welchem Ergebnis die führen sollen. Denn so pauschal ist Deine
Schlussfolgerung nicht richtig:
>> counter = (counter + 1) % 60;> Ist im dem Punkt erheblich robuster
Mampf F. schrieb:> Dr. Sommer schrieb:>> Mampf F. schrieb:>>> Das meiste funktioniert nur, wenn es nicht woanders verändert wird ;-)>>>> Ein "counter = 72;" ist schnell mal versehentlich getippt. Ein>> "reinterpret_cast<std::uint8_t&> (counter3) = 72;" zur Umgehung des>> Zugriffsschutzes nicht so sehr.>> Ja, man sollte schon wissen, was man macht ;-)>> Passiert selten, dass ich irgendetwas tippe, was ich nicht möchte - im> Rausch eventuell, aber wenn man wieder nüchtern ist, klärt sich das> meistens.
Hast Du keine Kollegen?
Jim M. schrieb:> counter = ++counter % 10;
Jetzt muss ich selber (da ich es nicht ganz verstehe) fragen:
Bedeutet die obige Operation dass der:
a) counter um jeweils 10 erhöht wird
oder
b) um jeweils 1 erhöht wird bis er 10 erreicht und dann 0 wird?
Alex W. schrieb:> Bedeutet die obige Operation dass der:
Diese Operation ist ein Fehler und führt zu beliebigem Verhalten. Keine
deiner Antworten ist richtig. Wurde doch schon erläutert.
Kaj schrieb:> Undefined Behavior
Cman schrieb:> Wieso ist nochmal so etwas in C nicht gut?>> counter = counter++ % 10;> Danke
Weil du innerhalb einer Berechnung den Wert einer Variable für's
Ergebnis verwendest und zugleich selbige veränderst.
Also die Regel für's gute Programmieren lautet:
Verändere NIE den Wert einer Variablen innerhalb der Anweisung, wo du
sie grad verwendest.
Richtig wäre
counter = (counter + 1) % 10;
Bedenke dabei auch mal, daß Modulo eine komplette Division beinhaltet.
Falls du es einrichten kannst, den zulässigen Bereich auf eine
Zweierpotenz zu beschränken, dann wäre das Ganze einfacher und schneller
mit einer Maskierung zu erledigen:
counter = (counter + 1) & 0xF; // zum Beispiel
W.S.
Rolf M. schrieb:> ++counter;> while (counter > 59) {counter -= 60;}>> Ich schreibe in so einem Fall die Inkrememntierung eh normalerweise in> eine eigene Zeile.
Du merkst aber, daß die ganze Diskussion hier ein bissel verkehrt geht.
Jetzt sind wir nämlich bei Uhrzeiten und bei solchen Dingen ist es
einfach besser, eben NICHT in Sekunden, Minuten und Stunden zu zählen,
sondern einfach geradeaus die Zeit in Sekunden (oder wer will, in
Millisekunden) - und das Darstellen der Uhrzeit Programmteilen zu
überlassen, die aus einem long, de die Zeit enthält, eine textuelle
Darstellung in H:M:S zu machen.
W.S.
Wilhelm M. schrieb:> Hast Du keine Kollegen?
nicht wenn es ums Programmieren geht - hauptberuflich bin ich Linux
Admin und die interessanten Sachen mach ich nur nebenbei xD
W.S. schrieb:> und das Darstellen der Uhrzeit Programmteilen zu> überlassen, die aus einem long, de die Zeit enthält, eine textuelle> Darstellung in H:M:S zu machen.
Das ist aber langsam und daher für Mikrocontroller ggf. nicht so
geeignet.
Mampf schrieb:> Wilhelm M. schrieb:>> Hast Du keine Kollegen?>> nicht wenn es ums Programmieren geht - hauptberuflich bin ich Linux> Admin und die interessanten Sachen mach ich nur nebenbei xD
Dann ist Dir bestimmt auch klar, dass Du auch Dein eigener Kollege sein
kannst - wenn Du z.B. Deinen eigene Code nach 3 Monaten wieder siehst
;-)
Es ist durchaus normal, dass man zuerst an die Modulo-Operation denkt,
wenn man einen Ringzähler implementieren will. Sie schreibt sich sehr
übersichtlich und sie funktioniert natürlich auch.
Da sie aber ein richtiges (Modulo-)Ergebnis auch für beliebige
Eingangswerte liefert, zeigt, dass sie wesentlich mehr macht als für
einen Ringzähler notwendig ist, wie z.B. für Restklassenmathematik. So
wird z.B. aus 345 mod 10 eben die 5, bei der if-Abfrage aber nicht. Um
das zu leisten, kompiliert sie eben auch deutlich größer als die
if-Abfrage.
Für einen Ringzähler benötigt man nur die effizientere if-Abfrage.
Dr. Sommer schrieb:> Normal-Intelligenten Programmierern wie mir passiert es leider öfter> mal, dass man versehentlich was falsches tippt.
Ja, aber dann habe ich einen Fehler in meinem Programm und den sollte
ich suchen. Da ist es dann auch richtig, wenn mein Programm zunächst
Mist abliefert und mir den Hinweis gibt, dass noch was im Argen ist.
Wilhelm M. schrieb:>> Profis™ machen das so:>> Aber Du weißt doch, dass Du in diesem Forum eine C Frage nicht mit C++> beantworten darfst!
Insbesondere, wenn genau das in der Überschrift steht …
Vom generierten Code her wird es kaum ein Unterschied sein, ob man das
nun explizit mit einem if testet oder in die Klassendefinition pfercht.
HildeK schrieb:> Ja, aber dann habe ich einen Fehler in meinem Programm und den sollte> ich suchen
Typische C-Mentalität. Hauptsache der Compiler übersetzt das Programm
fix ohne zu meckern, damit man es schnell starten kann... und mit der
Fehlersuche beginnen. Wenn der Fehlerfall aber nur sehr selten eintritt,
findet man ihn ggf. nicht und liefert ein fehlerhaftes Programm aus.
Daher sollte man sich die Möglichkeiten einer Hochsprache (hier: C++,
trifft aber mit unterschiedlichem Level auch auf andere Sprachen zu) zu
nutze machen und so programmieren, dass der Compiler das Programm
strenger auf Fehler prüfen kann (hier: Nutzung einer Klasse und
Zugriffsschutz). So werden eine Menge Fehler sofort erkannt und man
verschwendet weniger Zeit mit Testen und Debuggen.
Jörg W. schrieb:> Vom generierten Code her wird es kaum ein Unterschied sein, ob man das> nun explizit mit einem if testet oder in die Klassendefinition pfercht.
Eben drum ist es attraktiv - besserer Schutz vor Fehlern ohne
Performance-Einbuße.
Jörg W. schrieb:> Wilhelm M. schrieb:>>> Profis™ machen das so:>>>> Aber Du weißt doch, dass Du in diesem Forum eine C Frage nicht mit C++>> beantworten darfst!>> Insbesondere, wenn genau das in der Überschrift steht …
Das ist die Baumarktverkäufermentalität ...
Wilhelm M. schrieb:> Jörg W. schrieb:>> Wilhelm M. schrieb:>>>> Profis™ machen das so:>>>>>> Aber Du weißt doch, dass Du in diesem Forum eine C Frage nicht mit C++>>> beantworten darfst!>>>> Insbesondere, wenn genau das in der Überschrift steht …>> Das ist die Baumarktverkäufermentalität ...
Du meinst, der Kunde fragt nach X, und man empfiehlt ihm, dass Y alles
viel besser kann? (Obwohl X es durchaus auch könnte)
Ja, da wirst du Recht haben … so gesehen seid ihr hier
Baumarktverkäufer. :)
Jörg W. schrieb:> Wilhelm M. schrieb:>> Jörg W. schrieb:>>> Wilhelm M. schrieb:>>>>> Profis™ machen das so:>>>>>>>> Aber Du weißt doch, dass Du in diesem Forum eine C Frage nicht mit C++>>>> beantworten darfst!>>>>>> Insbesondere, wenn genau das in der Überschrift steht …>>>> Das ist die Baumarktverkäufermentalität ...>> Du meinst, der Kunde fragt nach X, und man empfiehlt ihm, dass Y alles> viel besser kann? (Obwohl X es durchaus auch könnte)
Wo steht der Baumarkt mit so einem Verkäufer? Da würde ich gerne mal
hin!
Ich würde mich sehr freuen über: "X kann es, aber mit folgenden
Nachteilen. Ich empfehle aber Y, weil es folgende Vorteile hat".
Anstatt zu hören: "Ja, nimm X. Was anderes gibt es nicht und wir haben
das immer so gemacht."
Dr. Sommer schrieb:> Das ist aber langsam und daher für Mikrocontroller ggf. nicht so> geeignet.
Nö. Überhaupt nicht.
Bedenke mal, daß das schlichte Hochzählen der Uhrzeit im Timertick alle
1 oder 10 ms erfolgt, eine eventuelle Darstellung als Text in einem
Ausdruck oder Display jedoch nur dann, wenn der betreffende Inhalt
aufgebaut wird, also im menschlichen Maße von nicht schneller als einige
100 ms.
Und da wäre nochwas zur Bilanz:
Auch dann, wenn du sek,min,hr bereits als einzelne Variablen hättest,
würdest du zwecks Darstellung als 10:09:53 jedesmal eine
Ausgabekonvertierung benötigen, die wiederum mehrere Divisionen braucht.
Da ist es wesentlich einfacher und schneller und platzsparender, sowohl
die Division als auch Modulo mit ein paar ldiv's aus der Uhrzeit im long
zu erledigen.
W.S.
W.S. schrieb:> Bedenke mal, daß das schlichte Hochzählen der Uhrzeit im Timertick alle> 1 oder 10 ms erfolgt
Wenn das denn so ist, und nicht irgendeine andere Form der (schnellen)
Simulation o.ä. Hardware-RTC's zählen übrigens auch die Sekunden,
Minuten, Stunden einzeln hoch, und zwar jede Dezimal-Ziffer einzeln. Das
wird auch einen Grund haben.
W.S. schrieb:> platzsparender
Wenn man eine Routine für long-Division im Code hat? Die ist bestimmt
länger als ein paar bedingte Blöcke.
Hallo,
Wilhelm M. schrieb:> Ich würde mich sehr freuen über: "X kann es, aber mit folgenden> Nachteilen. Ich empfehle aber Y, weil es folgende Vorteile hat".
Ja, genau.
Ich stelle mir gerade vor wie ein Kunde, der von einem Holzbrett eine
Stück absägen will, gezielt nach einer passenden Säge fragt und vom
Baumarktmitarbeiter gesagt bekommt, das er doch besser in einen
CNC-Holz-Hobel-Bohr-Sägen-Fräsen-Schleifer nebst 1-wöchigem
Bediengrundkurs investieren soll.
Obwohl es auch ein Billigfuchsschwanz aus der Grabbeltheke getan hätte.
rhf
P.S.:
Wenn ich mir hier manchmal so die "Vereinfachungen" die durch den
Gebrauch von "geeigneteren" Programmiersprachen als C ansehe, überkommt
mich eine ungutes Gefühl.
Roland F. schrieb:> das er doch besser in einen> CNC-Holz-Hobel-Bohr-Sägen-Fräsen-Schleifer nebst 1-wöchigem> Bediengrundkurs investieren soll.
Im Gegensatz zu echten Werkzeugen kostet die Nutzung von Klassen und
Kapselung kein Geld. C++-Compiler sind für viele Plattformen gratis/open
source verfügbar.
Roland F. schrieb:> P.S.:> Wenn ich mir hier manchmal so die "Vereinfachungen" die durch den> Gebrauch von "geeigneteren" Programmiersprachen als C ansehe, überkommt> mich eine ungutes Gefühl.
Angst, was zu verpassen? Ineffizienter als andere zu arbeiten?
Dr. Sommer schrieb:> Im Gegensatz zu echten Werkzeugen kostet die Nutzung von Klassen und> Kapselung kein Geld.
Sie ist aber auch nicht "for free" zu haben: die dahinter liegenden
Konzepte zu verstehen, braucht mehr Einarbeitungsaufwand. Im
kommerziellen Umfeld ist Zeit letztlich auch Geld. Wenn ich sowas nur
einmal für eine simple Uhr brauche, wird sich das kaum lohnen, wenn ich
das wirklich immer wieder verwenden kann, ist das was anderes.
Jörg W. schrieb:> wenn ich> das wirklich immer wieder verwenden kann, ist das was anderes.
Mechanismen zur Abstraktion und Kapselung kann man für alle Arten der
Programmierung nutzen, nicht nur für eine Uhr. Daher lohnt sich die
Einarbeitungszeit mehrfach.
Jörg W. schrieb:> Wenn ich sowas nur> einmal für eine simple Uhr brauche
Wie wahrscheinlich ist es, dass man im kommerziellen Umfeld einmal so
ein Massenprodukt wie eine Uhr programmiert, und dann nie wieder
etwas...
Wenn man direkt eine High-Level-Sprache statt C lernen würde (z.B. Java
oder Python), wäre der Einarbeitungsaufwand sowieso gering, da kommen
solche Dinge ganz natürlich.
Und wer weiß, vielleicht lernt man ja sogar schneller wenn man erst
grundlegende Prinzipien mit Python lernt, und dann für Controller auf
C++ umsteigt, anstatt sich sofort mit den Eigenheiten des letztgenannten
herumschlagen zu müssen...
Hallo,
Dr. Sommer schrieb:> Im Gegensatz zu echten Werkzeugen kostet die Nutzung von Klassen und> Kapselung kein Geld.
Und die permanente Einarbeitung in immer komplexere Abstraktionsebenen
un immer komplexere Sprachmittel ist kostenlos?
Und welche Abstraktionsebene und welches Sprachmittel ist eigentlich das
Beste?
Und sind auch alle Programmierer auf dem neuesten Stand und beherrschen
all diese Werkzeuge?
> Angst, was zu verpassen? Ineffizienter als andere zu arbeiten?
Ich bin in der glücklichen Lage weder mit Elektronik noch mit
Softwareerstellung beruflich zu tun zu haben, für mich ist das alles nur
Hobby.
Aber wenn ich dann hier lese wie aus
wird, stelle ich mir die Frage ob das wirklich nötig ist. Nicht alles
was möglich ist, ist auch sinnvoll.
rhf
P.S.:
Vor einiger Zeit habe ich mal gelesen das Linus Torvalds wohl weiterhin
darauf besteht das der Linux-Kernel in C geschrieben wird. Langsam wird
mir klar warum.
Dr. Sommer schrieb:> Wenn man direkt eine High-Level-Sprache statt C lernen würde (z.B. Java> oder Python), wäre der Einarbeitungsaufwand sowieso gering, da kommen> solche Dinge ganz natürlich.
Trotzdem kannst du das nicht vergleichen. Ich bin mir ziemlich sicher,
dass keiner unserer Python-schreibenden und C-kennenden Programmierer
(mich eingeschlossen :) in der Lage wäre, das in C++ passend aus dem
Stegreif zu formulieren, ohne es irgendwo erstmal nachlesen zu gehen.
Die Syntax ist halt eine reichlich andere, es hilft dir da nicht viel,
die zugrunde liegenden Konzepte zu kennen.
Hallo,
Dr. Sommer schrieb:> Und wer weiß, vielleicht lernt man ja sogar schneller wenn man erst> grundlegende Prinzipien mit Python lernt, und dann für Controller auf> C++ umsteigt, anstatt sich sofort mit den Eigenheiten des letztgenannten> herumschlagen zu müssen...
Erinnert mich an meine Schulzeit, als uns mal ein Lehrer erklärt hat das
es viel besser wäre sich erst einmal intensiv mit Latein und Griechisch
zu beschäftigen, danach könnte man alle anderen Sprachen spielend
einfach lernen. Wir wollten aber eigentlich nur Englisch sprechen und
lesen können...
rhf
Jörg W. schrieb:> Dr. Sommer schrieb:>> Wenn man direkt eine High-Level-Sprache statt C lernen würde (z.B. Java>> oder Python), wäre der Einarbeitungsaufwand sowieso gering, da kommen>> solche Dinge ganz natürlich.>> Trotzdem kannst du das nicht vergleichen. Ich bin mir ziemlich sicher,> dass keiner unserer Python-schreibenden und C-kennenden Programmierer> (mich eingeschlossen :) in der Lage wäre, das in C++ passend aus dem> Stegreif zu formulieren, ohne es irgendwo erstmal nachlesen zu gehen.> Die Syntax ist halt eine reichlich andere, es hilft dir da nicht viel,> die zugrunde liegenden Konzepte zu kennen.
So ein kleines Template wie das obige, um bspw. einen saturierenden
ganzzahligen, numerischen DT zu modellieren, lernt man als Studierender
auf einer vernünftigen heutigen Hochschule im BA-Informatik im 2.
Semester.
Aber viel wichtiger ist es sich klar zu machen, dass die primitiven DT
entweder als das genutzt werden sollen, was sie darstellen, oder man
sich andernfalls eigene DT schafft, um das zu modellieren, was man
modellieren will.
Roland F. schrieb:> Und die permanente Einarbeitung in immer komplexere Abstraktionsebenen> un immer komplexere Sprachmittel ist kostenlos?
Nein, aber zahlt sich aus in der eingesparten Zeit der Fehlersuche.
Roland F. schrieb:> Und welche Abstraktionsebene und welches Sprachmittel ist eigentlich das> Beste?
Das ist schwierig zu beantworten und hängt stark von der Anwendung ab.
Allgemein ist OOP extrem verbreitet und für vieles geeignet. Im
Embedded-Bereich hat sich erfahrungsgemäß ein "wenig OOP" mit einfachen
Patterns wie "Observer" und "State", und natürlich wie hier zur
Datenkapselung, als gut bewiesen. Fortgeschrittene Programmierer können
hier noch von der Metaprogrammierung profitieren, da sie Effizienz &
Abstraktion kombiniert. Teilweise sind auch
Pipes&Processors-Architekturen sinnvoll; Simulink z.B. macht nichts
anderes.
Roland F. schrieb:> wird, stelle ich mir die Frage ob das wirklich nötig ist. Nicht alles> was möglich ist, ist auch sinnvoll.
Die Klassendefinition schreibt man genau 1x und verpackt sie in eine
Bibliothek, oder nutzt eine fertige. Danach sieht man nur noch:
1
Counter<uint8_t,3>counter3;
2
counter3.count();
Btw, kleiner Nebeneffekt: Wenn man an verschiedenen Stellen zählt, muss
man nicht jedes Mal das Maximum (3) wiederholen, man kann es an
zentraler Stelle konfigurieren.
Roland F. schrieb:> Vor einiger Zeit habe ich mal gelesen das Linus Torvalds wohl weiterhin> darauf besteht das der Linux-Kernel in C geschrieben wird. Langsam wird> mir klar warum.
Hauptsächlich weil es damals keine guten C++-Compiler gab. Wenn man sich
den Linux Source-Code so anschaut, fragt man sich warum man auf Biegen
und Brechen in C Dinge tun muss, für die es in C++ explizit bessere
Mittel gibt.
Jörg W. schrieb:> Die Syntax ist halt eine reichlich andere, es hilft dir da nicht viel,> die zugrunde liegenden Konzepte zu kennen.
Aber sie lernt sich schnell wenn man die Konzepte kennt. Wie gesagt
lohnt sich die Lern-Zeit. Oder würdest du auf die Nutzung eines CAD
verzichten und lieber mit Stift&Papier layouten, weil das Lernen des CAD
so lange dauert?
Roland F. schrieb:> danach könnte man alle anderen Sprachen spielend> einfach lernen. Wir wollten aber eigentlich nur Englisch sprechen und> lesen können...
Wenn Latein & Griechisch viel einfacher und schneller lernbarer wären
als Englisch, wäre dein Vergleich sinnvoll.
Arduino Fanboy D. schrieb:> Das funktioniert nur, wenn man immer, und für alle Zeiten, GARANTIEREN> kann, dass counter nicht woanders verändert wird.
Kann man das dann nicht einfach "einkapseln"?
1
intTimerTick(void){
2
staticseconds=0;
3
4
seconds++;
5
if(seconds>59)seconds=0;
6
7
returnseconds;
8
9
}
Wilhelm M. schrieb:> So ein kleines Template wie das obige, um bspw. einen saturierenden> ganzzahligen, numerischen DT zu modellieren, lernt man als Studierender> auf einer vernünftigen heutigen Hochschule im BA-Informatik im 2.> Semester.
Du meinst ich muss ein Informatikstudium machen um einen Sekundenzähler
zu proggen? ;-)
C-Laie schrieb:> Kann man das dann nicht einfach "einkapseln"?
Und was wenn du mehr als 1 Zähler brauchst? Von einer statischen
Variable gibt es immer nur genau eine...
C-Laie schrieb:> Kann man das dann nicht einfach "einkapseln"?>>
1
>intTimerTick(void){
2
>staticseconds=0;
3
>seconds++;
4
>if(seconds>59)seconds=0;
5
>returnseconds;
6
>}
7
>
>>> Du meinst ich muss ein Informatikstudium machen um einen Sekundenzähler> zu proggen? ;-)
Wenn Du Deine obige "Lösung" als richtig ansiehst, dann ja.
W.S. schrieb:>Dr. Sommer schrieb:>> W.S. schrieb:>>> und das Darstellen der Uhrzeit Programmteilen zu>>> überlassen, die aus einem long, de die Zeit enthält, eine textuelle>>> Darstellung in H:M:S zu machen.>> Das ist aber langsam und daher für Mikrocontroller ggf. nicht so>> geeignet.>> Nö. Überhaupt nicht.
Aber hallo. Die Umrechnung von Sekunden, womöglich noch Sekunden seit
dem Epoch (UNIXTIME) in HH:MM:SS ist aufwendig. Ohne Division und
Modulo-Operation würde man das nicht schreiben wollen.
Die Komponenten einfach zu inkrementieren und den Überlauf per if() zu
fangen, ist da deutlich weniger aufwendig.
> Bedenke mal, daß das schlichte Hochzählen der Uhrzeit im Timertick alle> 1 oder 10 ms erfolgt, eine eventuelle Darstellung als Text in einem> Ausdruck oder Display jedoch nur dann, wenn der betreffende Inhalt> aufgebaut wird, also im menschlichen Maße von nicht schneller als einige> 100 ms.
Das ist gleich doppelt falsch. Zum einen war bisher noch gar nicht die
Rede davon, daß es ein Inkrement der Zeit häufiger als einmal pro
Sekunde geben würde. Für ein Programm, das die Uhrzeit in irgendeiner
Form anzeigt, braucht man die Formatierung als HH:MM:SS aber bei jedem
Inkrement. Das Aufschieben der Umrechnung spart dann gar nichts ein.
Zum zweiten muß ich dir jetzt deine eigene Argumentation entgegen
halten: wenn der Interrupt jede Millisekunde kommt, dann kannst du doch
genausogut einen großen Millisekundenzähler inkrementieren und die
Umrechnung desselben in Sekunden, Minuten usw. einfach an eine höhere
Schicht delegieren. Macht aber kein Mensch so. Statt dessen wird man im
Interrupt einen lokalen Zähler bis 1000 (bei 1ms Intervall) zählen
lassen und bei dessen Überlauf den Sekundenzähler (bzw. die Zeit-struct)
inkrementieren. Mit anderen Worten: man macht genau jene Operation, die
du bei den Sekunden verteufelst, für den Millisekundenzähler.
> Auch dann, wenn du sek,min,hr bereits als einzelne Variablen hättest,> würdest du zwecks Darstellung als 10:09:53 jedesmal eine> Ausgabekonvertierung benötigen, die wiederum mehrere Divisionen braucht.
Keineswegs. Eine zweistellige Dezimalzahl kann man auch ohne Divisionen
nach ASCII konvertieren. Einen 32-bittigen Sekundenzähler in Sekunden,
Minuten und Stunden zu zerlegen - das will man nicht ohne Division
machen.
Und wenn man auch die letzten paar Zyklen einsparen will, dann speichert
und rechnet man Sekunden, Minuten und Stunden als gepackte BCD-Zahlen.
Hallo,
Dr. Sommer schrieb:> Die Klassendefinition schreibt man genau 1x und verpackt sie in eine> Bibliothek, oder nutzt eine fertige. Danach sieht man nur noch:>
1
Counter<uint8_t,3>counter3;
2
>counter3.count();
Prima, jetzt hast du eine universell nutzbare Klasse. Wenn man das jetzt
für jedes "Problem" macht, hat man doch irgend eine ungeheuer große
Anzahl an universell einsetzbaren Klassen. Wie behält man da den
Überblick? Kannst du dich auch in ein paar Jahren nach erinnern und
findest die damalige Lösung sofort wieder?
Und vielleicht ist die Klasse doch nicht so universell einsetzbar und
man muss wieder eine eine neue Klasse entwerfen, die dann wiederum von
anderen Basisklassen abhängt, deren Funktionsweise man erst mal
verstehen muss.
Ich könnte mir vorstellen, das es da viel einfacher ist statt immer
weiter zu abstrahieren das "Problem" einfach mal einfach anzugehen.
Insbesonders wenn es sich, wie im Ausgangsbeitrag, um ein eher triviales
"Problem" handelt.
Verstehe mich nicht falsch, die von dir beschriebene Vorgehensweise ist
sicherlich bei umfangreicher und komplexer Software sinnvoll. Aber alles
und jedes zu abstrahieren weil es ja vielleicht, möglicherweise,
eventuell nochmal woanders Verwendung findet, scheint mir nicht sehr
sinnvoll zu sein.
rhf
Dr. Sommer schrieb:> Und was wenn du mehr als 1 Zähler brauchst? Von einer statischen> Variable gibt es immer nur genau eine...
und was mache ich wenn ich eine Mondrakete brauche? Wäre da (Hier die
LieblingsProgrammierSprache einsetzen) nicht auch überfordert? ;-)
Roland F. schrieb:> end eine ungeheuer große> Anzahl an universell einsetzbaren Klassen. Wie behält man da den> Überblick?
Mit einer vernünftigen Dokumentation. Geht bei den riesigen Bibliotheken
von Java oder .Net ja auch.
Genau so eine Counter-Klasse habe ich übrigens in mehreren Projekten im
Einsatz, mit noch ein paar weiteren Funktionen. Es ist enorm praktisch,
den maximalen Zählerstand zentral konfigurieren zu können. Daher ja, es
ist sinnvoll so einfache Dinge zu kapseln. Viele der Algorithmen in
der C++-Standardbibliothek sind auch nicht besonders komplex; aber
dennoch ist es praktisch, sie nutzen zu können.
Das Hauptargument für Simulink beispielsweise ist, dass es vorgefertigte
Komponenten für Verzögerungsglieder, Hysteresen, Filter... hat. Die sind
für sich genommen auch alle relativ simpel, aber dennoch schwören viele
darauf. Das kann man doch in C++ auch so machen. Man muss das Rad nicht
ständig neu erfinden.
HyperMario schrieb:> und was mache ich wenn ich eine Mondrakete brauche? Wäre da (Hier die> LieblingsProgrammierSprache einsetzen) nicht auch überfordert? ;-)
Ja, deswegen wird da Ada verwendet. Das ist ähnlich komplex wie C++, ist
aber noch strikter und führt genau die Paradigmen, die ich angesprochen
habe (Typsicherheit, Kapselung) noch weiter aus.
Dr. Sommer schrieb:> für die es in C++ explizit bessere Mittel gibt.
Das mag sein. C++ war hier aber nirgends gefordert. Und die Diskussion
driftet wie schon des öfteren ab.
Mach doch einen neuen Tread auf für das Thema in C++.
C-Polizei? Nein es hat da nichts mit zu tun. Es wird schlicht am Thema
vorbei diskutiert. Thema verfehlt, 6, setzen ;)
Jetzt geht mir ein Licht auf, warum es bisher nicht geklappt hat, die
Uhrzeit auf Dezimalsystem umzustellen. Man sollte sie auf binär
umstellen.
1 Tag = 32 Stunden á 64 Minuten á 64 Sekunden = 65536 Sekunden.
Das weicht gar nicht mal so stark von unserem aktuellen Empfinden ab.
Stunden und Minuten vergehen ca. 24% schneller, die Sekunde gut 32%
schneller. Da gewöhnt man sich dran !
Und man kann super effizient mit AND und SHIFT rechnen.
;-)
CaptainA schrieb:> 1 Tag = 32 Stunden á 64 Minuten á 64 Sekunden = 65536 Sekunden.
Hat was. Die 64 = 8·8 kann man gut an 8 Fingern abzählen.
Einfach die Daumen abhacken. Die taugen eh zu nix ;)
Wilhelm M. schrieb:> Peter D. schrieb:>> Dr. Sommer schrieb:>>> Sonst kommt die C-Polizei!>>>> Das nicht, aber ein Großteil der Leser wird>> damit nichts anfangen können.>> Die C-Polizei lauert hinter jeder Ecke ...
Die sollte noch viel schärfer durchgreifen, denn
diese penetrante C++-Missioniererei in aber wirklich
JEDEM C-Thread nervt ganz gewaltig.
Hallo, nachdem sich die ganze Geschichte wieder einmal zu einem kleinen
Glaubenskrieg entwickelt hat, frage ich einfach mal, wer denn zum Teufel
schreibt sowas in C ??? Dachte wir reden über Ćontroller und da ist erst
in der hohen Liga an C, oder... zu denken. Auf meinem AVR mach ich doch
sowas nicht?!!!
OK, die "Zusammenklick-Fraktion" aber sonst? Und das aufgekommenen
Beispiel mit Uhr (HH:MM:SS), das macht man doch nicht in einer
Hochsprache. Da ist genau Packed-BCD angesagt...
Gruß und viel Spass, Rainer
Rainer V. schrieb:> frage ich einfach mal, wer denn zum Teufel schreibt> sowas in C ???
Jeder, der mehr als eine Controllerfamilie verwendet.
> Dachte wir reden über Ćontroller und da ist erst> in der hohen Liga an C, oder... zu denken.
Wie kommst Du darauf?
Rainer V. schrieb:> Auf meinem AVR mach ich doch sowas nicht?!!!
Wenn Dein AVR einer der ganz, ganz winzkleinen Tinys ist, dann kann man
darauf kein C verwenden, aber auf jedem anderen sehr wohl, und das
geht bestens. Auch schon auf einem etwas größeren Tiny wie z.B. dem
Tiny85 (auf dem kann man sogar C++ einsetzen, wie es im Arduino-Umfeld
üblich ist).
Egon D. schrieb:> Jeder, der mehr als eine Controllerfamilie verwendet.
Sorry, aber ich dachte wir sprechen über "Bastler".
Und ein Profibereich, wo irgendwas für mehrere Controllerfamilien
gebastelt wird, ist mir "neu"...bzw. ehr unbekannt. Egon könnte sich
aber durchaus am berühmten "Siemensfenster" befinden, und dort werden
wahrscheinlich portable Klassen für jeden erdenklichen Unsinn
geschrieben. Sorry, sollte nicht persönlich werden, ist es aber...
Gruß Rainer
Roland F. schrieb:> Erinnert mich an meine Schulzeit, als uns mal ein Lehrer erklärt hat das> es viel besser wäre sich erst einmal intensiv mit Latein und Griechisch> zu beschäftigen, danach könnte man alle anderen Sprachen spielend> einfach lernen. Wir wollten aber eigentlich nur Englisch sprechen und> lesen können...
Das läuft auf die Frage hinaus "Wozu brauch ich Bildung?"
..und abgesehen davon versteht man mit etwas Latein im Kreuz auch
Englisch deutlich besser als ohne, dito französisch, dito sogar deutsch.
W.S.
Dr. Sommer schrieb:> Hauptsächlich weil es damals keine guten C++-Compiler gab. Wenn man sich> den Linux Source-Code so anschaut, fragt man sich warum man auf Biegen> und Brechen in C Dinge tun muss, für die es in C++ explizit bessere> Mittel gibt.
Nein. Es geht nicht um die Compiler! Z.B.:
http://harmful.cat-v.org/software/c++/linus
Es geht um die Mentalität der Programmierer und letztendlich um die
Lesbarkeit des Codes.
Dr. Sommer schrieb:> Ja, deswegen wird da Ada verwendet.
... und noch öfter C. Natürlich mit entsprechender statischer und
dynamischer Analyse etc, genauer gesagt: mit allen Analysetools.
Roland F. schrieb:> Verstehe mich nicht falsch, die von dir beschriebene Vorgehensweise ist> sicherlich bei umfangreicher und komplexer Software sinnvoll.
Eher: Ein notwendiges Übel um sauber zu bleiben.
> Aber alles> und jedes zu abstrahieren weil es ja vielleicht, möglicherweise,> eventuell nochmal woanders Verwendung findet, scheint mir nicht sehr> sinnvoll zu sein.
Vor allem führt es direkt zu Unit-Tests. Es ist nichts falsch mit
Unit-Tests, aber insgesamt führt es zu hunderten kleinen Routinen,
Codeschnippseln, die alle getestet sind, 100% Pfad- und Code- und
Branch- und wasfürabdeckung. Man kreiert ein eigenes Sprachuniversum,
dass völlig o.k. ist, wenn es von 1000en genutzt wird und es eine
Dokumentation gibt, wie Dr. Sommer selbst schreibt:
Dr. Sommer schrieb:> Mit einer vernünftigen Dokumentation. Geht bei den riesigen Bibliotheken> von Java oder .Net ja auch.
Aber in meinem Universum von 2, 10 oder 20 Entwicklern ist ein Überblick
per parallel gepflegter Doku (auch wenns Doxygen ist) ein Misstand.
Bei einer API, OK, bei Minifunktionen: Nein.
W.S. schrieb:> ..und abgesehen davon versteht man mit etwas Latein im Kreuz auch> Englisch deutlich besser als ohne, dito französisch, dito sogar deutsch.
Full agree...und italiänisch, und spanisch und und und,
ich hatte zwar nur eine "4" in Latein, aber das hilft für alle
"romanischen" Sprachen! Und dann gleich noch die ähnlich (sinnfreie)
Frage: wozu soll ich Mathe lernen.
Ja,Ja...
Gruß Rainer
Rainer V. schrieb:> Sorry, aber ich dachte wir sprechen über "Bastler".
Auch die haben in den letzten Jahrzehnten den Gebrauch anderer
Programmiersprachen als Assembler durchaus kennengelernt, und sie sind
gerade dadurch nicht mehr so sehr an die eine Controllerfamilie
gebunden, mit der sie angefangen haben.
Die große Arduinofraktion beispielsweise kommt mit AVRs, ARMen,
irgendwelchen Expressif-Kernen (ESP8266 etc.) und (wenn man "Arduino"
durch das kompatible "Energia" ersetzt) auch MSP430, C2000 etc. ohne
größere Probleme zurecht.
Und das sind Bastler.
Rainer V. schrieb:> Egon D. schrieb:>> Jeder, der mehr als eine Controllerfamilie verwendet.>> Sorry, aber ich dachte wir sprechen über "Bastler".
Wo nimmst Du das her? Es ging um eine C-Frage.
> Und ein Profibereich, wo irgendwas für mehrere> Controllerfamilien gebastelt wird, ist mir "neu"...> bzw. ehr unbekannt.
Außer Klitschen, die ausschließlich eigene Geräte
entwickeln, hat meiner Erfahrung nach niemand den
Luxus, sich die Controllerfamilie in jedem Falle
aussuchen zu können.
Und da man nicht jedesmal das Rad in Assembler neu
erfinden will, wird eben die einzige "Hochsprache"
verwendet, die auf praktisch jedem Controller
verfügbar ist...
> Egon könnte sich aber durchaus am berühmten> "Siemensfenster" befinden, und dort werden> wahrscheinlich portable Klassen für jeden> erdenklichen Unsinn geschrieben.
Klassen in C? Verwechselst Du da nicht gerade
etwas?
Rufus Τ. F. schrieb:> Und das sind Bastler.
Ich gebe dir voll Recht, aber die diversen Fragen, nicht nur hier im
Forum, lassen mich an Vielem zweifeln...
Egon D. schrieb:> Wo nimmst Du das her? Es ging um eine C-Frage.
OK, habe mich zu weit herausgehängt...trotzdem scheint mir die Frage,
wie der eines Erstklässlers, der verzweifelt seine Schultüte sucht...
Gruß Rainer
Rainer V. schrieb:> aber die diversen Fragen, nicht nur hier im Forum, lassen mich an Vielem> zweifeln...
Das ist etwas, was Dir unbenommen ist.
Nur: Der Bastler hat sich seit den 80ern stark verändert; wer damals
froh um jeden Informationsfitzel war, den er irgendwo ergattern konnte
und Datenbücher & Datenblätter gesammelt hat (und als Einschlafliteratur
nutzte), wer also nicht auf die allumfassende Informationsquelle
"Internet" zugreifen konnte, der hat eine komplett andere
Herangehensweise an die Materie als derjenige, der heute mit einer
unglaublichen Vielzahl phantastisch leistungsfähiger, spottbilliger und
mit Unmengen an Dokumentation, Beispielcode, Entwicklungssystemen etc.
ausgestatteten Systemen konfrontiert ist.
Und ja, auch damals, als Bastler in den 80ern, hat man in der Lernphase
Verständnisprobleme und komplett unrealistische Ideen gehabt, die früher
oder später beim harten Kontakt mit der Realität starben (ich kann mich
erinnern, als Schüler mal die Idee gehabt zu haben, daß man ja auch 'nen
stinknormalen Audiocassettenrecorder nutzen könnte, um damit Videos
aufzunehmen -- ich wusste damals halt nicht wirklich viel bzw. eher
überhaupt nichts darüber, was "Video" eigentlich ist). Heute, wo jede
Idee, jede Frage sofort ins Internet gestopft wird, wird so etwas
natürlich augenscheinlicher.
Das aber ist dann auch schon der große Unterschied.
Daß damals viele Bastler auch keinerlei Grundlagenwissen hatten, fiel
nicht so sehr auf, weil sie mit ihren Fragen nicht die Reichweite
hatten, die heute das Internet bietet.
Rainer V. schrieb:> Egon D. schrieb:>> Wo nimmst Du das her? Es ging um eine C-Frage.>> OK, habe mich zu weit herausgehängt...trotzdem> scheint mir die Frage, wie der eines Erstklässlers,> der verzweifelt seine Schultüte sucht...
Wessen Frage? Die des TO?
Ich finde die Frage eigentlich berechtigt, denn es ist
nach meinem Empfinden überhaupt nicht offensichtlich,
dass "counter++" nicht für "(counter+1)" steht, sondern
für "counter = (counter+1)".
Diese verdeckte Zuweisung ist halt eine der unzähligen
Fallen in C, aber daraus zu folgern, dass man C nicht
einsetzen sollte, hieße, das Kind mit dem Bade auszu-
schütten.
Es genügt ja völlig, wenn man MISRA folgt und die
Operatoren "++" und "--" nicht zusammen mit anderen
Operatoren in ein und demselben Ausdruck verwendet.
Man muss ja nicht gleich so weit gehen wie ich und
"++" bzw. "--" gar nicht mehr einsetzen...
Egon D. schrieb:> denn es ist nach meinem Empfinden überhaupt nicht offensichtlich, dass> "counter++" nicht für "(counter+1)" steht, sondern für "counter => (counter+1)".
Du hast also in C noch nie eine auf die übliche Art und Weise
formulierte for - Schleife gesehen?
1
for(i=0;i<10;i++)
2
{
3
}
Ich fände es hochgradig unoffensichtlich, stünde x++ für den Ausdruck "x
+ 1".
Damit würde vor allem die Schleife irgendwie nicht funktionieren.
Rufus Τ. F. schrieb:> Egon D. schrieb:>> denn es ist nach meinem Empfinden überhaupt nicht>> offensichtlich, dass "counter++" nicht für "(counter+1)">> steht, sondern für "counter = (counter+1)".>> Du hast also in C noch nie eine auf die übliche Art> und Weise formulierte for - Schleife gesehen?
Doch, natürlich -- aber wer sagt Dir, dass ich die nicht
genauso beschissen finde?
> for (i = 0; i < 10; i++)> {> }
Ja... das sieht in Tcl exakt genauso aus (glaube ich).
Gottseidank habe ich den Luxus, in 90% aller Fälle einfach
1
2
foreach ding $dingliste {
3
...
4
}
schreiben zu können, und in den restlichen 9.99% schreibe ich
1
set i 0
2
while { $i < 10 } {
3
...
4
incr i
5
}
Die einzige Falle hierbei besteht darin, das "incr i" nicht
zu vergessen, aber das nehme ich gern in Kauf.
Ich greife ja niemanden an, der meine speziellen Abneigungen
nicht teilt -- aber ich nehme mir im Gegenzug die Freiheit,
die Operatoren mit Seiteneffekt wie auch die Tatsache, dass
Zuweisungen AUSDRÜCKE sind (und keine Anweisungen) zum
kränkesten zu zählen, was C zu bieten hat.
Rufus Τ. F. schrieb:> Du hast also in C noch nie eine auf die übliche Art und Weise> formulierte for - Schleife gesehen?
Liebe Leute, ok, es geht natürlich weiter...demnächst werden wir noch
über eine reine Constanten- oder Variablen-Def. in C diskutieren...ist
doch blöd oder..
Gruß Rainer
Rainer V. schrieb:> Liebe Leute, ok, es geht natürlich weiter...demnächst> werden wir noch über eine reine Constanten- oder> Variablen-Def. in C diskutieren...ist doch blöd oder..
???
Warum beteiligst Du Dich an einem C-Thread, wenn Dich
C nicht interessiert?
Ich bin dabei, meinen Horizont von Assembler, Pascal
und Tcl auf C auszudehnen, und ich finde Diskussionen,
was man in C tun und lassen sollte, ziemlich nützlich.
Wo liegt Dein Problem?
Egon D. schrieb:> Warum beteiligst Du Dich an einem C-Thread, wenn Dich> C nicht interessiert?>> Ich bin dabei, meinen Horizont von Assembler, Pascal> und Tcl auf C auszudehnen, und ich finde Diskussionen,> was man in C tun und lassen sollte, ziemlich nützlich.>> Wo liegt Dein Problem?
Sorry, auch als "Nicht-C'ler" fand ich die Frage des TO erst einmal
lesenswert! Dass sich dahinter reiner "Kinderkram" verbirgt, habe ich
erst jetzt verstanden. Wie gesagt, die Foren sind voll von diesen
Fragen, die sich ein "Klicker" - immerhin manchmal - stellt.
Cman schrieb:> Wieso ist nochmal so etwas in C nicht gut?>> counter = counter++ % 10;> Danke
Zur Erinnerung noch mal die Frage des TO...
Gruß Rainer
Egon D. schrieb:> Doch, natürlich -- aber wer sagt Dir, dass ich die nicht genauso> beschissen finde?
Das ist als Anfänger völlig normal. Da kann ich doch genauso gut i=i+1;
hinschreiben, oder inc i oder egal.
Am Ende (nach einiger Zeit Erfahrung, zählt aber nur Lesbarkeit, im
großen Stil. Noch weiter sind die Mathematiker, mit kurzen variablen,
globalen Konventionen und jeder Menge Sonderzeichen.
Ob du es glaubst oder nicht, Ziel ist Lesbarkeit.
Achim S. schrieb:> Egon D. schrieb:>> Doch, natürlich -- aber wer sagt Dir, dass ich die>> nicht genauso beschissen finde?>> Das ist als Anfänger völlig normal.
Sicher -- aber Du vergisst dabei, dass ich zwar
C-Anfänger bin, aber kein Programmieranfänger.
Konstrukte, die mir zu abseitig sind, ersetze ich
durch die kanonische Form.
> Ob du es glaubst oder nicht, Ziel ist Lesbarkeit.
Ich verstehe Dein Argument nicht. Natürlich ist Lesbarkeit
(unter der Randbedingung der Korrektheit) oberstes Ziel,
aber genau deshalb verwende ich bestimmte Konstrukte
NICHT.
Ja, man DARF sich den Daumen platthauen oder in den Fuß
schießen -- aber bin ich wirklich dazu VERPFLICHTET?
Rainer V. schrieb:> Egon D. schrieb:>> Warum beteiligst Du Dich an einem C-Thread, wenn Dich>> C nicht interessiert?>>>> Ich bin dabei, meinen Horizont von Assembler, Pascal>> und Tcl auf C auszudehnen, und ich finde Diskussionen,>> was man in C tun und lassen sollte, ziemlich nützlich.>>>> Wo liegt Dein Problem?>> Sorry, auch als "Nicht-C'ler" fand ich die Frage des> TO erst einmal lesenswert! Dass sich dahinter reiner> "Kinderkram" verbirgt, habe ich erst jetzt verstanden.
Tut mir leid... ich bin offenbar wirklich zu dumm, um zu
verstehen, was Du meinst. Dieser "Kinderkram", wie Du es
nennst, ist das, was den WESENTLICHEN Aufwand beim Lernen
von C verursacht.
> Wie gesagt, die Foren sind voll von diesen Fragen,> die sich ein "Klicker" - immerhin manchmal - stellt.
???
Jörg W. schrieb:> Du vergisst, dass die Eingangszeile eine Kurzform ist von> counter = (counter = counter + 1) % 10;> Siehst du jetzt die doppelte Zuweisung?
Ja, schon -- aber wieso ist das fehlerhaft?
Modulo bindet stärker als die (äußere) Zuweisung.
Das Plus in der Klammer bindet stärker als die
Zuweisung in der Klammer.
Also würde ich davon ausgehen, dass zuerst counter
um Eins erhöht wird, dieser erhöhte Wert dann
"counter" zugewiesen wird (was nichts ändert), dann
der Divisionsrest bestimmt wird, und schließlich das
Ergebnis wiederum counter zugewiesen wird.
Wo liegt mein Denkfehler?
Jörg W. schrieb:> Siehst du jetzt die doppelte Zuweisung?
Nein, das sieht man eben nicht. Das weiss man, wenn man weiss, was C mit
++ macht. Aber die Zuweisung sieht man an der Stelle genau nicht.
Achim S. schrieb:> lesbarer (schneller, robuster) ist If(++counter > 59) {counter = 0;}
Kommt drauf an.
Ist der Überlauf eine Zahl <> 2^n, wird auf einem µC für Modulo eine
Softdivision aufgerufen: Das If ist schneller. Ist der Überlauf 2^n,
wird bei Modulo einfach mit einer Bitmaske ge-AND-ed: Das If ist
langsamer. Ist der Compiler entsprechend klever, optimiert er das If
weg.
CaptainA schrieb:> Man sollte sie auf binär> umstellen.> 1 Tag = 32 Stunden á 64 Minuten á 64 Sekunden = 65536 Sekunden.
Funktioniert so aber nur auf Rechnern mit Halbbit-Arithmetik.
Egon D. schrieb:> Ja, schon -- aber wieso ist das fehlerhaft?>> Modulo bindet stärker als die (äußere) Zuweisung.> Das Plus in der Klammer bindet stärker als die> Zuweisung in der Klammer.> Also würde ich davon ausgehen, dass zuerst counter> um Eins erhöht wird, dieser erhöhte Wert dann> "counter" zugewiesen wird (was nichts ändert), dann> der Divisionsrest bestimmt wird, und schließlich das> Ergebnis wiederum counter zugewiesen wird.>> Wo liegt mein Denkfehler?
Kein Denkfehler! Einfach nur eine Folge des "Sequence-Point"-Konzepts
und das = halt keiner ist. Diese c-faq erklärt es relativ kompakt:
http://c-faq.com/expr/seqpoints.html
Und ja, das muss man nicht wissen, das muss man nichtmal ahnen! Und man
muss es nicht verstehen. Es reicht, wenn man man defensiv programmiert
und Warnungen einschaltet.
Dann kommt man die ersten Jahre auch über die Runden und fragt sich,
warum er bei a=a++; warnt, aber nicht bei a++; oder a++;a=a; .... Und
stellt dann meist fest, dass es eh von vornherein Blödsinn war.
Egon D. schrieb:> Diese verdeckte Zuweisung ist halt eine der unzähligen Fallen in C
Naja. Sie ist ein Tribut daran, dass man sowas machen konnte:
1
char*cp,c;
2
3
cp=...;
4
5
// …
6
7
while((c=*cp++)!='\0'){
8
// tu was mit "c"
9
}
und dabei selbst mit den primitiven Compilern der damaligen Zeit auf
einer PDP-11 im generierten Assemblercode die
post-increment-Adressierung dieser Maschine 1:1 abbilden konnte, mithin
in C an die Effizienz von Assembler herankam.
Das Pendant zu post-increment war auf der PDP-11 übrigens pre-decrement
(beides zusammen brauchte man ohnehin für Stack oder das normale
Befehlslesen), weshalb uralter C-Code eben auch wirklich nur foo++ oder
--foo benutzt, aber praktisch nie ++foo oder foo--. pre-increment und
post-decrement gab es nicht als direkte Adressierungsarten, das hätte
dann zwei Befehle gebraucht.
Egon D. schrieb:> Modulo bindet stärker als die (äußere) Zuweisung.
Bindung beschreibt nur, in welcher Folge die gedachte Klammerung liegt,
aber nicht, in welcher Folge die tatsächliche Abarbeitung der Anweisung
durch den Compiler umgesetzt werden muss.
Ansonsten würde die Sprache dem Compiler laufend bei der Optimierung im
Weg herumstehen.
Die hier schon mehrfach genannten "sequence points" sind dann die
Stellen, an denen der Zustand der hypothetischen Maschine, durch die die
Anweisungen abgearbeitet sind, wieder mit der Realität übereinstimmen
müssen.
Jörg W. schrieb:> Egon D. schrieb:>> Diese verdeckte Zuweisung ist halt eine der>> unzähligen Fallen in C>> Naja. Sie ist ein Tribut daran, dass [...]
Ja, ich weiss.
Ich wollte auch nicht wieder die (k+1)-te Runde
dieser Diskussion einläuten, sondern damit nur sagen:
Die Schöpfer von C hatten bestimmte gute Gründe, damals
solche Konstrukte in die Sprache einzubauen.
Und wir haben heute gute Gründe, nicht unbedingt alle
Konstrukte aktiv zu verwenden, die die Sprache bietet --
einfach weil heute eben nicht damals ist. Die Entwicklung
ist weitergegangen, die Schwerpunkte und Notwendigkeiten
haben sich verschoben.
Egon D. schrieb:> Und wir haben heute gute Gründe, nicht unbedingt alle Konstrukte aktiv> zu verwenden, die die Sprache bietet
Das ist gewiss auch richtig, wenngleich man in der for-Anweisung sicher
nur ungern drauf verzichten würde.
Man muss sich halt jedes Mal sein Werkzeug durchdenken, das man benutzt.
Wilhelm M. schrieb:> So ein kleines Template wie das obige, um bspw. einen saturierenden> ganzzahligen, numerischen DT zu modellieren, lernt man als Studierender> auf einer vernünftigen heutigen Hochschule im BA-Informatik im 2.> Semester.
Das mag sein, allerdings habe ich nie Informatik (E-Technik) studiert
und arbeite trotzdem als Softwareentwickler.
Du kannst nicht von jedem Programmierer verlangen, dass er auf dem
aktuellen Stand der Entwicklung ist und alle Konstrukte sowohl aktiv als
auch passiv vollständig nutzen kann. Schon garnicht für C++, welches als
Multi-Paradigmen-Sprache extrem komplex ist.
Dr. Sommer schrieb:>> Und die permanente Einarbeitung in immer komplexere Abstraktionsebenen>> un immer komplexere Sprachmittel ist kostenlos?> Nein, aber zahlt sich aus in der eingesparten Zeit der Fehlersuche.
In erster Linie würde das bei meinem Arbeitgeber dazu führen, dass der
Code nicht durch die Code-Review kommt. Die verwendeten - und erwarteten
- Patterns in der verwendeten Codebasis sind festgelegt. Das gilt
übrigens auch für Fremdcode gleicher Funktion, mit dem ich zu tun habe
(der dann natürlich andere Patterns, andere Abstraktionsebenen und
andere Datentypen benutzt). Es handelt sich um eine strikte Untermenge
von C++.
Warum legt man sowas fest, statt überall die optimale Lösung zu haben?
Weil man damit mittelmäßige Programmierer, die man hat, sinnvoll
produktiv einsetzen kann. Weil man damit viele strukturelle Fehler
vermeiden kann. Weil man damit den Reviewer entlastet. Und so weiter.
In C++ ist es problemlos möglich, dass ein einfach aussehendes "x = x +
1" eine zweitätige Einarbeitung benötigt, bis man wirklich verstanden
hat, was es eigentlich tut.
> Die Klassendefinition schreibt man genau 1x und verpackt sie in eine> Bibliothek, oder nutzt eine fertige.
Wie gesagt, das wäre bei uns nicht möglich. Und die Gründe dafür finde
ich sowohl nachvollziehbar als auch sinnvoll.
> Aber sie lernt sich schnell wenn man die Konzepte kennt. Wie gesagt> lohnt sich die Lern-Zeit. Oder würdest du auf die Nutzung eines CAD> verzichten und lieber mit Stift&Papier layouten, weil das Lernen des CAD> so lange dauert?
Das hängt davon ab, ob die erwartete Zeitersparnis durch "Lernen und
optimiertes Verfahren benutzen" verglichen mit "ineffizientes Verfahren
benutzen" positiv ist. Lernen ist Aufwand, den Luxus kann ich mir nicht
immer dann gönnen, wenn es gerade sinnvoll wäre.
Mit anderen Worten: Ich automatisiere Dinge nur dann, wenn ich damit
rechne, sie hinreichend oft benutzen zu müssen, oder sie bereits so oft
genug benutzt habe, dass die Automatisierung trivial ist.
Achim S. schrieb:> Vor allem führt es direkt zu Unit-Tests. Es ist nichts falsch mit> Unit-Tests, aber insgesamt führt es zu hunderten kleinen Routinen,> Codeschnippseln, die alle getestet sind,
Ich behaupte, dass eines der Hauptprobleme bei "das Problem in immer
kleinere Teile schnetzeln" nicht mehr die einzelnen Teile sind, sondern
deren Komposition. Die einem Problem inhärente Komplexität muss irgendwo
wieder auftauchen, sonst ist das Problem nicht gelöst. Tausend kleine
Fragmente sehe ich bei vielen Projekten nicht als Lösung, sondern als
Problem.
Zuviel Abstraktion verschleiert den Blick aufs Wesentliche (wie in der
Philosophie auch). Außerdem lassen sich über stark abstrahierte Objekte
nur noch wenig konkrete Aussagen treffen, was aber nicht überall klar
ist, wo die Abstraktion verwendet wird. Und am Ende hat man einen
Zähler, der mal für Zahlen bis 60 entworfen wurde, dessen API aber
wesentlich weiter reicht als dessen Implementation.
Egon D. schrieb:> Die Schöpfer von C hatten bestimmte gute Gründe, damals> solche Konstrukte in die Sprache einzubauen.> Und wir haben heute gute Gründe, nicht unbedingt alle> Konstrukte aktiv zu verwenden, die die Sprache bietet --> einfach weil heute eben nicht damals ist.
Die vorhandenen Konstrukte prinzipiell zu verbieten, ist aber auch keine
vernünftige Lösung. Selbst ein eher misslungene Teile (wie z.B.
Bitfelder oder goto) lassen sich in bestimmten Fällen äußerst sinnvoll
einsetzen - oder sind nur schwer zu vermeiden. Sprachen, in denen solche
Konstrukte fehlen, bieten oft Alternativen.
> Die Entwicklung ist weitergegangen, die Schwerpunkte> und Notwendigkeiten haben sich verschoben.
Dafür gibt es alternative Programmiersprachen. Die Entwicklung geht zwar
weiter, auch in C (K&R C und C11 sind nicht die gleiche Sprache) - aber
an den Grundfesten rütteln kann man eben nicht so einfach.
Jörg W. schrieb:> Egon D. schrieb:>> Und wir haben heute gute Gründe, nicht unbedingt>> alle Konstrukte aktiv zu verwenden, die die Sprache>> bietet>> Das ist gewiss auch richtig, wenngleich man in der> for-Anweisung sicher nur ungern drauf verzichten würde.
Naja, niemand muss meine abseitigen Vorlieben teilen --
ich erwarte nur, dass ich wegen meiner andersartigen
Orientierung nicht als dumm, faul oder unprofessionell
beschimpft werde ;)
S. R. schrieb:> Egon D. schrieb:>> Die Schöpfer von C hatten bestimmte gute Gründe, damals>> solche Konstrukte in die Sprache einzubauen.>> Und wir haben heute gute Gründe, nicht unbedingt alle>> Konstrukte aktiv zu verwenden, die die Sprache bietet -->> einfach weil heute eben nicht damals ist.>> Die vorhandenen Konstrukte prinzipiell zu verbieten,> ist aber auch keine vernünftige Lösung.
Es geht (mir) doch überhaupt nicht um "verbieten".
Es ist einfach so, dass C eine Anzahl Konstrukte kennt,
die damals aus Effizienzgründen sinnvoll waren, die aber
heute die Lesbarkeit der Programme nicht unbedingt
verbessern.
Niemand sagt, dass man die Konstrukte heute nicht mehr
einsetzen darf -- davon ist keine Rede. Wer mir aber
ausgerechnet diese Konstrukte als DIE großen Errungen-
schaften von C verkaufen will, offenbart ein in meinen
Augen sehr verdrehtes Verständnis von Softwareentwicklung.
Hochsprachen sind NUR für den Menschen da, der Computer
ist auch mit Binärzahlen zufrieden.
>> Die Entwicklung ist weitergegangen, die Schwerpunkte>> und Notwendigkeiten haben sich verschoben.>> Dafür gibt es alternative Programmiersprachen.
Naja, auch diese Diskussion ist für mich schon durch:
Außer C (und Forth) wüsste ich keine Sprache, die
mit weitgehend identischer Syntax auf praktisch jedem
Prozessor verfügbar ist. (Assembler zählt nicht, da
ist nur der NAME identisch, nicht die Syntax.)
Insofern: Nein, es gibt leider nicht immer alternative
Programmiersprachen.
Achim S. schrieb:>> Wo liegt mein Denkfehler?>> Kein Denkfehler! Einfach nur eine Folge des> "Sequence-Point"-Konzepts und das = halt keiner ist.
Hmm.
Ich habe offenbar den subtilen Unterschied zwischen
"undefined behavior" und "unspecified behavior" nur
mangelhaft verstanden.
Ich bin davon ausgegangen, dass ein Freiheitsgrad in
der Reihenfolge der Auswertung besteht, der, abhängig
vom konkreten Compiler, zu unterschiedlichen Resultaten
führen kann (="unspecified behavior"?!).
Richtig scheint aber zu sein, dass der Compiler das
Konstrukt schlicht und ergreifend nicht übersetzen
muss (="undefined behavior"?!).
> Und ja, das muss man nicht wissen, das muss man nichtmal> ahnen! Und man muss es nicht verstehen.
Meine Güte... worauf habe ich mich eingelassen...
Egon D. schrieb:> Gottseidank habe ich den Luxus, in 90% aller Fälle einfach> foreach ding $dingliste {> ...> }> schreiben zu können,
Tja, es gibt da eine Sprache die das kann... Die nennt sich C++.
Dr. Sommer schrieb:> Egon D. schrieb:>> Gottseidank habe ich den Luxus, in 90% aller Fälle einfach>> foreach ding $dingliste {>> ...>> }>> schreiben zu können,>> Tja, es gibt da eine Sprache die das kann... Die nennt sich C++.
Oh, in einem C-Thread C++ erwähnen ... teuflisch. Tcl, etc. ist erlaubt,
aber doch kein C++.
Die Sprache C++ ist doch soo komplex, man muss(!) auch immer die ganze
Sprache mit allen (alten wie neuen) Features auf einmal(!) lernen,
deswegen ist das unbeherrschbar. Man muss(!) auch OOP benutzen, und
deswegen ist das nicht für µC einsetzbar. Und man muss(!) auch TMP
benutzen, dieses abstrakte Informatikerzeugs. Und dann noch die
Bibliothek dazu, von einem Mathematiker(!) ersonnen: ein Graus. Ja, und
Linus findet sie auch doof ... das verpflichtet.
Egon D. schrieb:> Richtig scheint aber zu sein, dass der Compiler das Konstrukt schlicht> und ergreifend nicht übersetzen muss (="undefined behavior"?!).
Noch schlimmer: mit einem UB braucht er auch alle Zeilen vor- und
nachher nicht mehr richtig zu übersetzen. Er kann sich dabei quasi
intern beliebig verschlucken und woanders Müll machen. Und dazu
braucht's keine Schachtelkonstrukte, es reicht ein int-überlauf mit i++;
Wilhelm M. schrieb:> Oh, in einem C-Thread C++ erwähnen ... teuflisch. Tcl, etc. ist erlaubt,> aber doch kein C++.
Du kannst natürlich machen was du willst, aber wer außer dir meint das
Tlc
"erlaubt" sei? Klingt nach ner faden Ausrede für sinnloses Gelaber über
eine andere Sprache (die übrigens für meine Hardware gar nicht existiert
und das geschwurbel da sinnlos ist).
In der Richtung war der beste Beitrag hier übrigens der mit dem Känguru
und den Daumen, versteht aber nicht jeder.
HyperMario schrieb:> Wilhelm M. schrieb:>> Oh, in einem C-Thread C++ erwähnen ... teuflisch. Tcl, etc. ist erlaubt,>> aber doch kein C++.>> Du kannst natürlich machen was du willst, aber wer außer dir meint das> Tlc> "erlaubt" sei? Klingt nach ner faden Ausrede für sinnloses Gelaber über> eine andere Sprache (die übrigens für meine Hardware gar nicht existiert> und das geschwurbel da sinnlos ist).
Ich glaube, Du hast jetzt grad gar nichts verstanden ;-)
Egon D. schrieb:> Wer mir aber ausgerechnet diese Konstrukte als DIE> großen Errungenschaften von C verkaufen will,> offenbart ein in meinen Augen sehr verdrehtes> Verständnis von Softwareentwicklung.
Jaein. Diese Konstrukte waren tatsächlich die großen Errungenschaften
von C, in ihrer Zeit. Heute sind sie das nicht mehr. Genauso wie das
Auto, der Taschenrechner, überhaupt Computer große Errungenschaften
ihrer Zeit waren.
Sie sind es alle heute nicht mehr.
Deswegen sind sie trotzdem nicht obsolet.
> Hochsprachen sind NUR für den Menschen da, der Computer> ist auch mit Binärzahlen zufrieden.
Es gibt Programmiersprachen, die möchten den Menschen maximal
bevorzugen. Mir ist aber ein ausgewogener Kompromiss wichtiger: Ich
möchte eine Sprache haben, die für mich benutzbar ist, aber trotzdem
noch die zugrundeliegende Maschine durchscheinen lässt.
Ich bin kein Webentwickler.
> Naja, auch diese Diskussion ist für mich schon durch:> Außer C (und Forth) wüsste ich keine Sprache, die mit weitgehend> identischer Syntax auf praktisch jedem Prozessor verfügbar ist.
Da gäbe es zum Beispiel C++. Außerdem kann man einige höhere Sprachen in
C-Code übersetzen lassen oder als C-Bibliothek einbinden.
Egon D. schrieb:> Ich habe offenbar den subtilen Unterschied zwischen> "undefined behavior" und "unspecified behavior" nur> mangelhaft verstanden.
Wenn in deinem Programm irgendwo "undefined behaviour" auftritt, dann
war das Programm schon vor dem Aufruf des Compilers fehlerhaft. Dem
Compiler steht es frei, das Programm fehlerfrei, fehlerhaft oder auch
garnicht zu kompilieren, und er muss dir auch nicht sagen, was davon er
gemacht hat.
Wenn in deinem Programm irgendwo "implementation-defined" behaviour
auftritt, dann durfte der Compilerhersteller entscheiden, was er tut
(und musste das auch dokumentieren). Das Verhalten ist damit vollständig
definiert (für diesen Compiler, in dieser Version, auf dieser
Plattform).
Ich habe in dem Zusammenhang noch nicht von "unspecified behaviour"
gehört, das ist meinem Verständnis nach schlicht dasselbe wie "undefined
behaviour".
> Ich bin davon ausgegangen, dass ein Freiheitsgrad in> der Reihenfolge der Auswertung besteht, der, abhängig> vom konkreten Compiler, zu unterschiedlichen Resultaten> führen kann (="unspecified behavior"?!).
Nein, die Auswertungsreihenfolge von "du schreibst eine Variable
mehrfach ohne Sequenzpunkt" ist schlicht undefiniert und damit auch das
Verhalten des Programms. Vor dem Compileraufruf, deswegen muss der
Compiler das Programm auch nicht übersetzen.
Ein Funktionsaufruf func(x++, x++, x++) ist ebenfalls undefiniert, aus
dem gleichen Grund.
Die Auswertung von if(x==0 && y==1 && z==2) hingegen muss von links nach
rechts erfolgen (und abkürzen).
Wilhelm M. schrieb:> HyperMario schrieb:>> Wilhelm M. schrieb:>>> Oh, in einem C-Thread C++ erwähnen ... teuflisch. Tcl, etc. ist erlaubt,>>> aber doch kein C++.>>>> Du kannst natürlich machen was du willst, aber wer außer dir meint das>> Tlc>> "erlaubt" sei? Klingt nach ner faden Ausrede für sinnloses Gelaber über>> eine andere Sprache (die übrigens für meine Hardware gar nicht existiert>> und das geschwurbel da sinnlos ist).>> Ich glaube, Du hast jetzt grad gar nichts verstanden ;-)
@Wilhem:
Ich glaube ich hatte es schon mal erwähnt:
Nutz die Zeit für Besseres. Schau dir CppCon Vorträge an, 2018 gibt's
wieder einen guten von Dan Saks, da hat man was von, anders als bei den
Diskussionen hier.
Carl D. schrieb:> Wilhelm M. schrieb:>> HyperMario schrieb:>>> Wilhelm M. schrieb:>>>> Oh, in einem C-Thread C++ erwähnen ... teuflisch. Tcl, etc. ist erlaubt,>>>> aber doch kein C++.>>>>>> Du kannst natürlich machen was du willst, aber wer außer dir meint das>>> Tlc>>> "erlaubt" sei? Klingt nach ner faden Ausrede für sinnloses Gelaber über>>> eine andere Sprache (die übrigens für meine Hardware gar nicht existiert>>> und das geschwurbel da sinnlos ist).>>>> Ich glaube, Du hast jetzt grad gar nichts verstanden ;-)>> @Wilhem:> Ich glaube ich hatte es schon mal erwähnt:> Nutz die Zeit für Besseres. Schau dir CppCon Vorträge an, 2018 gibt's> wieder einen guten von Dan Saks, da hat man was von, anders als bei den> Diskussionen hier.
Ja klar, aber ist doch wieder lustig hier ;.)
Habe schon fast alle gesehen: der von Andrew Sutton und Ben Deane
gehören m.E. zu den besten.
S. R. schrieb:> Ich habe in dem Zusammenhang noch nicht von "unspecified behaviour"> gehört, das ist meinem Verständnis nach schlicht dasselbe wie "undefined> behaviour".
Nein. Es ist wie implepementation-defined behavior, nur dass nicht
dokumentiert werden muss, wofür sich der Compiler-Hersteller entschieden
hat.
Ja, die ewigen Grabenkriege...nachdem seinerzeit unser Chefentwickler
sein Projekt - komplett in Lab-View - abgeschlossen hatte und seinen Hut
nahm, wurde beschlossen, den Code zwecks besserer Wartung (Chefidee..)
in C# (oder so) zu konvertieren. Nachdem das zu ernsten Problemen
führte, wurde C++ angesetzt! Dieses (interne!) Projekt gibt seitdem
(gefühlte 20 Jahre) einer Vollzeitkraft und diversen Hilfskräften Wasser
und Brot! Einzig der unglaubliche Erfolg des Produkts hat dies
ermöglicht...es erinnert mich fast an Stenkelfeld, die
Weihnachtsbeleuchtung...
Schönen Abend noch, Rainer
Cman schrieb:> Wieso ist nochmal so etwas in C nicht gut?>> counter = counter++ % 10;
Ehrlich, keine Ahnung :-)