Hallo,
wenn ich dieses Programm kompiliere, dann bekomme ich die Fehlermeldung
"Segmentation fault (core dumped)"
int factorial_rec(int num){
if(num==0)
return 1;
else
return num*factorial_rec(num--);
}
Dann ändere ich die letzte Zeile wie folgt:
return num*factorial_rec(num-1);
Und alles funktioniert einwandfrei. Warum denn das?!
(die Funktion bekommt nur positive Zahlen übergeben)
(GCC-Compiler)
Hallo,
n-- ist ein post-Dekrement
Du steckst also erst den momentanen Wert als Argument in Deinen
rekursiven Funktionsaufruf, erst dann wird (zu spät) der Wert
verringert. Und prompt gibt es eine Endlos-Rekusrsion.
Gruß Ralf
zitter_ned_aso schrieb:> (anscheinend wird zuerst dekrementiert und erst dann multipliziert)
Bei (num-1) wird überhaupt nicht dekrementiert.
Was genau SOLL die Zeile denn eigentlich tun?
Die Zeile SOLL nichts tun. Es ist eine Korrektur der obigen Funktion.
Das ist die komplette Funktion:
int factorial_rec(int num){
if(num==0)
return 1;
else
return num*factorial_rec(--num);
}
Mit postfix-Dekrementierung bekomme ich also eine
Fehlermeldung(segmentation fault-Fehlermeldung, die oben schon vom Ralf
erklärt wurde). Mit einer präfix-Dekrementierung - falsche Ergebnisse.
genau, bei
return num*factorial_rec(--num);
kann es durchaus passieren, dass zuerst decrementiert und dann
multipliziert wird, die Reihenfolge legt der Compiler/ Optimierer fest.
So etwas muss man vermeiden.
return num*factorial_rec(num-1);
passt hingegen, da num nicht verändert wird.
Die Warnung zeigt ja dass die Reihenfolge der return-Anweisung nicht
eindeutig ist.
Diese Meldung hatte ich auch. Und habe sie nicht beachtet weil es
eigentlich Wurscht ist, ob num*factorial_rec(--num) oder
factorial_rec(--num)*num zuerst berechnet wird.
Aber wenn zuerst dekrementiert wird (--num) und dann wird diese lokale
Variable auf dem Stack gespeichert (vor dem nächsten rekursiven Aufruf
der Funktion) - für die spätere Multiplikation (wenn der Stack wieder
abgebaut wird), dann ist diese Reihenfolge sehr wohl wichtig. (und ist
wohl die Ursache für die falsche Ergebnisse)
zitter_ned_aso schrieb:> (und ist> wohl die Ursache für die falsche Ergebnisse)
Nein. Der Grund fuer die falschen Ergenise und auch den SegFault ist
undefined behavior. Und genau das sagt dir der Compiler!
zitter_ned_aso schrieb:> Diese Meldung hatte ich auch. Und habe sie nicht beachtet
Tja, selbst schuld.
zitter_ned_aso schrieb:> funktioniert übrigens einwandfrei ;-)
Ist aber genauso falsch, da der C(++) Standard hier kein Verhalten
definiert und der Compiler das beliebig umsetzen kann; in der nächsten
Compiler-Version funktioniert das dann nicht mehr...
Dass man das Ergebnis bereits mit dem letzten rekursiven Aufruf auf dem
Stack hat?
Bei der Variante aus dem ersten Posting müsste man ja noch beim Abbauen
dieses Stacks auf alle zwischengespeicherten lokalen Variablen
zugreifen um das Endergebnis zu bekommen.
Fast... In dieser Variante muss nach der Rückkehr der innersten Funktion
nichts mehr getan werden; somit ist es überflüssig, überhaupt in die
äußeren Funktionsaufrufe hineinzuspringen, weil hier ohnehin nur noch
direkt das "return" ausgeführt würde. Daher kann der Compiler hier eine
"Tail-Recursion Optimization" einsetzen, d.h. es erfolgt überhaupt kein
rekursiver Funktionsaufruf mit Sicherung der Rücksprungadresse, sondern
ein simpler Sprung an den Anfang der Funktion, d.h. es wird eine
einfache Schleife daraus, welche auch keinen Stack Overflow auslösen
kann.
Tatsächlich ist der GCC sogar schlau genug das für beide Varianten zu
machen.
zitter_ned_aso schrieb:> int factorial_rec(int num){> if(num==0)> return 1;> else> return num*factorial_rec(num--);> }
Warum muß man als C-Programmierer eigentlich SO ETWAS schreiben? Aus
Übermut?
Erstens:
Es ist zwar vom Standpunkt der reinen Mathematik völlig egal, ob man nun
eine Rekursion zum Ausrechnen wählt oder eine simple Schleife.
Aber der rechentechnisch Gebildete weiß, daß es ein extrem albernes
Spiel ist, für die Fakultät von 30000 mal eben 30000 Funktionsumgebungen
auf dem Stack abzulegen, wenn es doch auch ganz simpel per ordinärer
Schleife geht.
Also ist hier gedankenabwesender Mutwillen im Spiel.
Zweitens:
Warum muß man eigentlich immer mit Seiteneffekten herumwerfen, wie hier
deutlich vorexerziert: Eine Zahl und deren Dekrementierung in der selben
Ergibtanweisung.
Immer nach dem Motto "bloß nicht auf der sicheren Seite arbeiten und
bloß nicht nachdenken und jedes getippte Textzeichen ist eigentlich
eines zuviel".
Dabei wäre das factorial_rec(num-1) genau das Richtige, weil es ja nur
drauf ankommt, den Funktionsaufruf mit einem um 1 niedrigeren Argument
zu tun, nicht jedoch darauf, die eigene Zahl "num" zu verändern.
Man könnte auch bieder in C programmieren und zu diesem Zwecke mehrere
Anweisungen hinschreiben - und das Optimieren dem Compiler überlassen.
Der kann das mittlerweile besser als ihr.
Inzwischen kommt mir so der Gedanke, daß man beim Entwurf von C besser
getan hätte, wenn man pre- und post-Inkrement/Dekrement sowie den ?
Operator und noch einiges Andere einfach weggelassen hätte. Auf lange
Sicht hätte das ne Menge Bockmist vermieden. Gelle?
W.S.
W.S. schrieb:> Warum muß man als C-Programmierer eigentlich SO ETWAS schreiben? Aus> Übermut?
Vielleicht weil man funktionale Sprachen vermisst, wo so etwas gängig
ist... Bei komplexeren Algorithmen als der Fakultät ist eine rekursive
Formulierung oft intuitiver und einfacher. Die Optimierung überlässt man
dann dem Compiler.
W.S. schrieb:> für die Fakultät von 30000 mal eben 30000 Funktionsumgebungen> auf dem Stack abzulegen
Dank Tail Recursion gar nicht nötig...
W.S. schrieb:> sowie den ?> Operator
Der ist aber sehr praktisch. Leider hat If-Else, anders als in
funktionalen Sprachen, in C ja keinen Return-Wert - der trinäre Operator
ist da so ein Trostpflaster. Das fördert die funktionale Programmierung
mit weniger Zustand und veränderlichen Variablen, und mehr direkten
Datenflüssen.
W.S. schrieb:> Man könnte auch bieder in C programmieren und zu diesem Zwecke mehrere> Anweisungen hinschreiben - und das Optimieren dem Compiler überlassen.
Mit etwas Erfahrung sind "--" und "?:" und Konsorten absolut gar kein
Problem. Professionelle C-Programmierer haben keine Lust extra
ausführlich zu tippen, nur damit ein paar Anfänger es leichter lesen
können. Ist ja schließlich kein Pascal...
Percy N. schrieb:> Es soll Leute geben, die für die Berechnung von> Binomialkoeffizienten> drei rekursiv berechnete Fakultäten verwenden.
In der richtigen™ funktionalen Sprache werden die redundanten Aufrufe
erkannt und wegoptimiert... Die unnötige Division allerdings vermutlich
nicht.
Dr. Sommer schrieb:> Professionelle C-Programmierer haben keine Lust extra> ausführlich zu tippen, nur damit ein paar Anfänger es leichter lesen> können. Ist ja schließlich kein Pascal...
Unsinn. Das ist der Standpunkt eines Fricklers, keines Profis. Ein Profi
legt höchsten Wert darauf, dass sein Code einfachst und intuitivst zu
lesen ist. Der Profi weiß, das jedes Zeichen, das er 'spart', seinen
Kollegen kostet.
Thomas M. schrieb:> Ein Profi legt höchsten Wert darauf, dass sein Code einfachst und> intuitivst zu lesen ist. Der Profi weiß, das jedes Zeichen, das er> 'spart', seinen Kollegen kostet.
Wenn man natürlich nur mit absoluten Anfängern zusammen arbeitet denen
ein "--" zu kompliziert ist... unnötig aufgeblasener Code senkt auch die
Lesbarkeit.
Dr. Sommer schrieb:> Professionelle C-Programmierer haben keine Lust extra> ausführlich zu tippen, nur damit ein paar Anfänger es leichter lesen> können. Ist ja schließlich kein Pascal...
Professionelle C-Programmierer können mit ihrer Tastatur umgehen und
wissen, dass in 90% der Fälle if/else genau so schnell getippt ist, wie
ein ternärer Operator. Professionelle Programmierer wissen auch, dass
leserlich geschriebener Code erwiesernermaßen schneller gelesen und
erfasst werden kann (gut, wer hätte das jetzt gedacht), und dass man
Code zwar nur einmal schreibt, aber gut und gern 100 Mal liest, die
Lesegeschwindigkeit also wichtiger ist.
Es gibt allerdings auch C-Programmierer, die entweder angeben wollen,
oder für jedes verbrauchte Zeichen zu viel bezahlen müssen, und deswegen
möglichst kryptischen Code schreiben. Im Idealfall sollte bei denen kein
Variablenname länger als zwei Zeichen sein, jede Variable möglichst oft
wiederverwendet werden, und die Anzahl der Sonderzeichen sich möglichst
stark an die Anzahl der vorkommenden Buchstaben annähern.
Dr. Sommer schrieb:> Wenn man natürlich nur mit absoluten Anfängern zusammen arbeitet denen> ein "--" zu kompliziert ist...
Jedes -- hat potentielle Seiteneffekte, die bedacht werden müssen, und
ist smit potientiell fehleranfällig, während es aber an den meisten
Stellen sowieso nix bringt. Es gibt also kaum Stellen, an denen es
sinnvoll ist (Schleifen z.B.), und die Lesbarkeit erhöht, ohne
glcihzeitig die Fehleranfälligkeit zu erhöhen.
Dr. Sommer schrieb:> unnötig aufgeblasener Code senkt auch die> Lesbarkeit.
Von unnötig aufgeblasen sind wir da noch weit weg.
Wirklich so unglaublich schwer lesbar? Benutz mal eine funktionale
Sprache wie Haskell, dann verstehst du warum das so elegant und intuitiv
ist, und woher es kommt. In C kriegt man leider nur ein trauriges Imitat
davon hin.
Dr. Sommer schrieb:> Wirklich so unglaublich schwer lesbar?
Nö, aber erwiesenermaßen langsamer lesbar als:
1
intfac(intx,intcollect){
2
if(x==0){
3
returncollect;
4
}
5
else{
6
returnfac(x-1,x*collect);
7
}
8
}
Selbst wenn diese Stelle nur um Sekundenbruchteile länger braucht um
gelesen zu werden: ein Programmierer liest jeden Tag tausende Zeilen
Code. Jeder Sekundenbruchteil, den das Gehirn länger braucht um eine
Stelle zu lesen und zu verstehen, summiert sich auf. Besonders toll wird
es dann, wenn da mal irgendwer ternäre Operatoren ineinander verschatelt
hat, macht richtig Spaß, das aufzudröseln.
Man fragt sich echt immer wieder, warum manche so ein massives Problem
damit haben, leserlichen Code zu schreiben. Man bekommt den Eindruck,
man will möglichst komplizierte Ausdrücke hinschreiben, um sich elitär
fühlen zu können (kommt bei dir ja auch raus, "nur Anfänger haben damit
ein Problem, blablub").
vn nn schrieb:> Nö, aber erwiesenermaßen langsamer lesbar als
Wie erwiesen? Wie würdest du so etwas in Ruby, Python, Haskell oder Lisp
schreiben? Auch mit 2x return? Oder würdest Du es da weglassen, da
überflüssig?
Das ursprüngliche Problem war mal:
Worin unterscheiden sich
n+1
und
n++
Da es offenbar Leute gibt, die das implizite Schreiben des erhöhten
Werts auf n nicht kennen, kann es nur eine Lösung geben:
Man benutzt dieses Feature nicht mehr. Keiner!
Oder lieg ich da falsch?
Zum Glück geht es nicht um n+2,
denn sonst müßte man auch diskutieren, ob n++ ++ ein passender Ersatz
wär.
Und zum Glück gibt es noch ein paar mäkelfreie Programmiersprachen, mit
denen man all das schreiben kann, was bei den anderen wegen
vorsätzlichem Missverstehen nicht möglich ist.
vn nn schrieb:> Nö, aber erwiesenermaßen langsamer lesbar als:
Ich kann die Dr. Sommer Version schneller lesen.
vn nn schrieb:> Man fragt sich echt immer wieder, warum manche so ein massives Problem> damit haben, leserlichen Code zu schreiben.
Ja echt! Warum schreibst du nicht leserlich? ... Vllt. weil Lesbarkeit
subjektiv ist?
Ich stimme dir zu. Geschachtelte ternäre Operatoren sind in den meisten
Fällen schlecht für die Lesbarkeit. Das stimmt aber auch für
geschachtelte if-else.
Für jemanden, der die Sprache kennt, sollte es möglich sein, den
Einzeiler von Dr. Sommer mit einem Blick zu erfassen. Mit die Sprache
kennen schließe ich alle aus, die erst in einem Forum nachfragen
müssten, was dieses ?:-Ding ist.
mh schrieb:> Ich kann die Dr. Sommer Version schneller lesen.
Ich auch, irritiert hat mich nur ein wenig, dass die Bedingung x == 0
nicht geklammert ist. Dachte, das wäre vorgeschrieben wie bei if oder
while.
mh schrieb:> Ich kann die Dr. Sommer Version schneller lesen.
Vielleicht kannst du auch schneller rennen oder ein Bier schneller
austrinken.
Aber das ist dem Rest der Welt herzlich egal. Das gepostete Beispiel ist
ein deutliches Negativbeispiel - es sieht kotzig aus und liest sich
grottenschlecht. Da bleibe ich lieber dort, wo's wichtig ist, bei
biederer Programmierung.
Meine Regel ist: Keine Husarenstückchen beim Programmieren und keine
Heldentaten in den Ausdrücken, sondern lieber ein paar Zeilen mehr.
Der eigentliche Knackpunkt ist, daß man bei solchen tollen Beispielen
zuerst gehörig nachdenken muß, was da eigentlich gemeint ist und was der
Compiler draus machen soll.
Und der TO hat genau DAS Fettnäpfchen mit seinem Fuß erwischt, was für
solche Fälle vorgehalten wird: eine Variable in einem Ausdruck zu
verwenden und zugleich selbige per Seiteneffekt zu verändern.
Volltreffer!
Wer sich für superoberschlau hält und/oder anständigen Stil als
"Anfängerkram" abtut, den bestraft die Toolchain mit ner Hausnummer.
W.S.
Und wo ist es leichter den Fehler in der Zeile 123 zu suchen?
if(x){
---if(y)
-------return ausdruck1; //Zeile 123
---else
-------return ausdruck2;
}
else{
---if(z)
-------return ausdruck3;
---else
-------return ausdruck4;
}
oder
return x?(y?ausdruck1:ausdruck2):(z?ausdruck3:ausdruck4); //Zeile 123
zitter_ned_aso schrieb:> Und wo ist es leichter den Fehler in der Zeile 123 zu suchen?
Beim ersten schön gegliedert, beim zweiten kein einziges Leerzeichen und
keinen Zeilenumbruch. Wie herrlich manipuliert…
Passen wir das mal entsprechend an und schreiben das erste als:
if(x)if(y)return ausruck1;else return ausdruck2;else if(z)return
ausdruck3;else return ausdruck4;
zitter_ned_aso schrieb:> Und wo ist es leichter den Fehler in der Zeile 123 zu suchen?
Vielleicht wäre es das Beste, dir einfach mal ein's hinter die Ohren zu
verpassen, denn schon die alten Weisen sagten: Eins auf den Hinterkopf
verbessert das Denkvermögen.
.. gelegentlich nur, meine ich.
Aber dennoch...
Kurzum: wer partout Bockmist schreiben will, der wird sich auch durch
Ratschläge nicht davon abbringen lassen.
Wobei ein Ratschlag nicht dasselbe ist wie eins hinter die Ohren,
sondern viel verbaler.
W.S.
Beim ersten schön gegliedert, beim zweiten kein einziges Leerzeichen und
keinen Zeilenumbruch.
----
Das sind jetzt keine Argumente, sondern Ausreden ;-)
Eine Anweisung pro Zeile ist mit Sicherheit besser für die Fehlersuche /
für's Testen (man kann dort jederzeit etwas auskommentieren/ergänzen).
Und beim "?:"-Operator schreibt man doch (immer) alles in eine Zeile.
Wobei ich den Code mit der "teil recursion"-Lösung sehr elegant finde.
Ein "?:"-Operator ist doch absolut OK und ist wahrlich kein Kandidat für
"The International Obfuscated C Code Contest"
https://www.ioccc.org/
Dr. Sommer schrieb:> W.S. schrieb:>> Husarenstückchen>> Ist das sowas wie ein Kosackenzipfel?
Was ist der Anlass dafür, den Zipfel gedanklich in der Nähe des Scrotums
anzuordnen?
Thematische Verbundenheit?
W.S. schrieb:> mh schrieb:>> Ich kann die Dr. Sommer Version schneller lesen.>> Vielleicht kannst du auch schneller rennen oder ein Bier schneller> austrinken.
Es wäre nett, wenn du den Rest meines Posts auch lesen würdest. Da geht
es um die Subjektivität von "Lesbarkeit".
W.S. schrieb:> Meine Regel ist: Keine Husarenstückchen beim Programmieren und keine> Heldentaten in den Ausdrücken, sondern lieber ein paar Zeilen mehr.
Genau, es ist DEINE Regel. Andere Leute haben andere Regeln.
W.S. schrieb:> Der eigentliche Knackpunkt ist, daß man bei solchen tollen Beispielen> zuerst gehörig nachdenken muß, was da eigentlich gemeint ist
Nicht "man" muss Nachdenken, sondern DU. Andere Leute können das mit
einem Blick verstehen. Und nein, dafür muss man nicht hochbegabt sein.
W.S. schrieb:> und was der Compiler draus machen soll.
Ich denke nicht sehr oft darüber nach, was der Compiler aus meinem
Quelltext machen soll. Ich gehe davon aus, dass der Compiler in 99% der
Fälle bessern Quelltext erzeugt, als ich.
Wenn die Ausdrücke nicht zu krude sind und man auch Leerzeichen
verwendet, kann ?: die Lesbarkeit deutlich erhöhen und der Scrollfinger
läuft nicht mehr heiß.
Je nach Styleguide kostet ja ein if/else mindestens 8 Zeilen.
Hier mal ein gut lesbares Beispiel für ?:
1
staticvoidcmd_set_mode(void)
2
{
3
uint8_tidx=get_par(mod_str,MOD_OFF,MOD_VOLT);
4
if(idx!=NOT_FOUND)
5
mode_set(idx)?answer_success():answer_err_mode();
6
}
P.S.:
Mit Rekursionen habe ich auch so meine Schwierigkeiten. Den meisten
Menschen fällt es deutlich leichter, in Schleifen zu denken.
Mit Rekursionen läßt man eben den Mathematiker raushängen. Manchmal muß
ich dann in das Assemblerlisting schauen, um zu verstehen, was die
Rekursion eigentlich machen soll. Der Compiler kann sie nämlich meistens
zu Schleifen optimieren.
Keiner N. schrieb:> Wie wär's denn, wenn mode_set gleich das richtige zurück gibt?
mode_set wird nicht nur im Remoteinterface aufgerufen, sondern noch an
anderen Stellen, z.B. zur Fehlerabschaltung.
Daher darf es nicht wild Nachrichten in einen Puffer schreiben.
Dr. Sommer schrieb:> Das fördert die funktionale Programmierung mit> weniger Zustand und veränderlichen Variablen,> und mehr direkten Datenflüssen.
Es gibt zwei Arten von Zuständen: Solche, die dem
Problem immanent sind, und "parasitäre", die nur
als Folge der sequenziell arbeitenden Maschine
entstehen.
So lange die Missionare der funktionalen
Programmierung nicht lernen, das zu unterscheiden,
verplempere ich keine Zeit mit ihnen -- da arbeite
ich lieber an der automatentheoretischen Deutung
der strukturierten Programmierung.
Egon D. schrieb:> Peter D. schrieb:>>> Je nach Styleguide kostet ja ein if/else>> mindestens 8 Zeilen.>> ???>> if (bedingung) {> do_something> } else {> do_somthing_else> }
if ()
{
...
}
else
{
...
}
vn nn schrieb:> Man fragt sich echt immer wieder, warum manche so> ein massives Problem damit haben, leserlichen Code> zu schreiben.
Mehrere Möglichkeiten:
1. Sie haben kein sicheres Gefühl dafür, wie guter,
leserlicher Code aussieht.
2. Ihnen fehlt die auf Erfahrung beruhende Einsicht,
dass man nicht nur für den Compiler schreibt,
sondern auch für den Menschen, der den Code in
einer Woche, einem Monat oder einem Jahr nochmal
anfassen muss.
3. Sie verwechseln "gut programmieren können" mit
"sämtliche schmutzigen Tricks kennen, die der
Compiler gerade noch durchgehen lässt".
4. Sie glauben TATSÄCHLICH, Mikrooptimierung führe
zu besseren Programmen.
> Man bekommt den Eindruck, man will möglichst> komplizierte Ausdrücke hinschreiben, um sich elitär> fühlen zu können (kommt bei dir ja auch raus, "nur> Anfänger haben damit ein Problem, blablub").
Das ist eine denkbare Möglichkeit, ja. Aber immer
daran denken: "Erkläre nichts durch bösen Willen,
was durch Blödheit hinreichend erklärbar ist."
Egon D. schrieb:> Mehrere Möglichkeiten:
5. Sie wollen einen auf dicke Hose machen und anderen zeigen, was sie
draufhaben. In der irrigen Annahme, ein erfahrener Programmierer ließe
sich von solchen Spielchen beeindrucken.
6. Sie sind so erfahren, dass sie so furchtbar komplizierte Dinge wie ?:
im Schlaf runterschreiben und überlesen, während sie sich stattdessen um
wichtige Dinge kümmern, wie die gesamte Architektur im Blick zu
behalten. Wenn man nicht jeden Pups umständlich ausschreibt kann man
auch komplexere Code-Abschnitte überblicken.
Egon D. schrieb:> da arbeite ich lieber an der automatentheoretischen Deutung der> strukturierten Programmierung
Du blickst durch funktionale Programmierung so gut durch dass du sie als
Zeitverschwendung ansiehst... und siehst strukturierte Programmierung
als das Heilmittel an?
Egon D. schrieb:> Solche, die dem Problem immanent sind
Welche Zustände sind denn der Berechnung der Fakultät immanent, und
müssen somit im Code ausgedrückt werden? Die rekursive Schreibweise
kommt da mysteriöserweise ganz ohne Zustände aus. Dass die
zugrundeliegende Maschine Zustände hat ist klar, aber bei echten
funktionalen Sprachen wird dies abstrahiert. Somit muss man sich
überhaupt nicht mit Zuständen rumplagen.
Egon D. schrieb:> Ihnen fehlt die auf Erfahrung beruhende Einsicht, dass man nicht nur> für den Compiler schreibt, sondern auch für den Menschen,
Eigentlich schreibt man nur für Menschen. Dass es auch der Compiler
frisst, ist eher ein Nebeneffekt.
Alle Kommentare und >95% der übrigen Zeichen sind nur für Menschen. Dem
Compiler sind Namen und Leerzeichen egal
Karl K. schrieb:> Es gibt aber definitiv "unlesbar".
Die hier aufgeführten Beispiele gehören aber definitiv nicht dazu.
Achim S. schrieb:> Eigentlich schreibt man nur für Menschen.
Aber nicht für jeden Menschen. Sondern für die, die damit arbeiten
müssen. Für meine Quelltexte bin ich das selbst. Also schreib ich sie
so, dass ich mich schnell darin zu recht finde. Egal, was Romanleser
dazu sagen.
Mach schrieb:> Je nach Styleguide sind ja trinäre Operatoren gaenzlich verboten ;-)
Für mich gehören manche Styleguides auch verboten.
Jobst Q. schrieb:> Für meine Quelltexte bin ich das selbst.
1-Mann-Frickelbuden-Rambo?
Jobst Q. schrieb:> Für mich gehören manche Styleguides auch verboten.
Mag sein, aber bei einer dreistelligen Anzahl Entwicklern für eine
Plattform-Software, wird eben nicht auf die persönlichen Vorlieben jedes
Einzelnen geachtet, sondern jeder nutzt dieselben Resharper-Settings und
hält sich an die Guidelines. so dass man sich auch in *Fremd*komponenten
schnell zurecht findet, u.a. beim Debuggen.
Jobst Q. schrieb:> Aber nicht für jeden Menschen. Sondern für die, die damit arbeiten> müssen. Für meine Quelltexte bin ich das selbst.
Sehe ich genauso. Ist aber nicht jedem klar. Manche verklären gewisse
mythische Grundsätze zum Selbstzweck, nur weil sie in einem gewissen
Kontext (und meist im Kontext absolute Beginner im ersten Jahr) sinnvoll
waren.
Achim S. schrieb:> Sehe ich genauso. Ist aber nicht jedem klar.
Weil nicht jeder in einer Umgebung arbeitet in der Code immer nur das
ureigenste Nugget des jeweiligen Entwicklers bleibt.
Wenn ihr Helden euch gegen nen Baum setzt, muss morgen ein anderer
Entwickler euren Schund übernehmen und bei der typischen Qualität von
selbstüberhöhenden Fricklern, heißt das meistens, wegschmeißen und neu
machen, weil unwartbar, undokumentiert, kein Testnetz. Unprofessioneller
Frickelscheiß halt, Hauptsache man hat sich einen darauf gehobelt, 3
zeilen vom if zu sparen.
Dr. Sommer schrieb:> "trinärer Operator genutzt"
Das Ding heißt ternärer Operator.
Dr. Sommer schrieb:> und> "unwartbar", "undokumentiert", "kein Testnetz"?
Weil Entwickler deren Hauptanliegen es ist, möglichsten kompakten Code
unter Ausnutzung aller möglichen Sprachfeinheiten zu produzieren, oft
nicht mal wissen was "wartbar" bedeutet, sind ja nur mit ihrem eigenen
Code beschäftigt. Dokumentation ist aus Prinzip minderwertige Arbeit und
eines genialen Entwicklers unwürdig, Designs sind eh überbewertet.
Testnetz heißt dann meist, er hats manuell mal ausprobiert und es hat
getan, muss reichen. Testcode schreiben ist schließlich langweilige
Zusatzarbeit.
Abradolf L. schrieb:> oft> nicht mal wissen was "wartbar" bedeutet
oft != immer. Also mal wieder eine Generalisierung.
Viel wichtiger in Sachen Wartbarkeit finde ich ja die Anwendung von OOP,
Design- und Architekturpatterns, Typsicherheit. Ob da irgendwo ein paar
?: versteckt sind ist doch völlig unerheblich.
Dr. Sommer schrieb:> Viel wichtiger in Sachen Wartbarkeit finde ich ja die Anwendung von OOP,> Design- und Architekturpatterns, Typsicherheit. Ob da irgendwo ein paar> ?: versteckt sind ist doch völlig unerheblich.
Wartbarkeit ist nun mal ein NFR was sich auf unterschiedlichen Leveln
auswirkt, das fängt bei der kleinen Unit an und geht bishin zur
Gesamtsystemarchitektur. Es gibt Fälle da erhöhen ?: die Lesbarkeit,
aber es als Mittel um Codezeilen zu sparen zu nutzen, ist halt daneben.
Abradolf L. schrieb:> Weil nicht jeder in einer Umgebung arbeitet in der Code immer nur das> ureigenste Nugget des jeweiligen Entwicklers bleibt.> Wenn ihr Helden euch gegen nen Baum setzt, muss morgen ein anderer> Entwickler euren Schund übernehmen und bei der typischen Qualität von> selbstüberhöhenden Fricklern, heißt das meistens, wegschmeißen und neu> machen, weil unwartbar, undokumentiert, kein Testnetz. Unprofessioneller> Frickelscheiß halt, Hauptsache man hat sich einen darauf gehobelt, 3> zeilen vom if zu sparen.
Es macht wenig Sinn, hier über die Qualität meiner Software zu
spekulieren.
Es ist wie bei jedem anderen Dokument auch, egal ob Bericht, Datenblatt
oder Zeitungsartikel. Du musst Deinen Schreibstil an die Zielgruppe
anpassen. Bei 1000 Zeilen ist es noch relativ egal, aber sobald Du
größeren Code hast ist geschwätziger Code mit noch geschwätzigeren
Kommentaren genauso schlimm wie Spaghetticode.
Und genauso, wie Du unter erfahrenen Kollegen manche Begriffe oder
Funktionsweisen voraussetzt, genauso wirst Du je erfahrener das Umfeld
ist umso kompakteren Code schreiben, solange er dadurch lesbarer ist.
Lesbarkeit und Wartbarkeit(*) sind (wenn man Performance nicht völlig
vernachlässigt) für 99% des Codes das einzige Kriterium.
Weniger Code-Zeilen bedeuten weniger Code den man lesen muss; es passt
mehr auf den Bildschirm das man so überblicken kann. Da doch mal lieber
Kommentare schreiben als Zeilen die nur { oder } enthalten.
Wenn es dann noch um nicht-kopierbare Typen geht wird's gern noch
umständlicher:
1
std::unique_ptr<std::vector<std::string>>ptr;
2
if(something){
3
ptr=allocateA();
4
}else{
5
ptr=allocateB();
6
}
7
useVector(std::move(ptr));
8
ptr->size();// Fehlermöglichkeit - ptr ist hier leer
vs
1
useVector(something?allocateA():allocateB());
und hier kann man "ptr" nicht versehentlich undefiniert verwenden
(Wartbarkeit!).
Achim S. schrieb:> Bei 1000 Zeilen ist es noch relativ egal, aber sobald Du> größeren Code hast
Programmierst Du im Notepad?
Aufteilung in Units / Includes, Codefaltung, Codebrowser... schonmal von
gehört?
Dr. Sommer schrieb:> es passt> mehr auf den Bildschirm das man so überblicken kann.
Vielleicht solltest Du Dir mal einen neuen Monitor gönnen. Es gibt
mittlerweile sogar welche mit Farbe, auch wenn 14" in Bernstein schon
hübsch aussieht.
Karl K. schrieb:> Es gibt> mittlerweile sogar welche mit Farbe, auch wenn 14" in Bernstein schon> hübsch aussieht.
Ich habe 2x 2560x1440 + 1x 1920x1080 ... Aber was nutzt eine ganze Wand
aus Monitoren, wenn man ständig hin und her gucken muss um die richtige
Stelle zu sehen, weil alles so elendig ausgedehnt ist. Klar kann man
auch Schriftgröße 6 auswählen, aber mit zunehmender Programmiererfahrung
nimmt die Sehkraft ab... :-)
Abradolf L. schrieb:> Weil Entwickler deren Hauptanliegen es ist, möglichsten kompakten Code> unter Ausnutzung aller möglichen Sprachfeinheiten zu produzieren, oft> nicht mal wissen was "wartbar" bedeutet, sind ja nur mit ihrem eigenen> Code beschäftigt. Dokumentation ist aus Prinzip minderwertige Arbeit und> eines genialen Entwicklers unwürdig, Designs sind eh überbewertet.> Testnetz heißt dann meist, er hats manuell mal ausprobiert und es hat> getan, muss reichen. Testcode schreiben ist schließlich langweilige> Zusatzarbeit.
Was sich manch einer so aus der Benutzung eines Operators heraus so
zusammenphantasiert, ist schon beeindruckend.
Dr. Sommer schrieb:> Ich habe 2x 2560x1440 + 1x 1920x1080 ...
Ich hatte mal vor 15 Jahren oder so einen Monitor mit 2048x1536. Seitdem
ist die (eigentlich besonders wichtige) vertikale Auflösung leider immer
mehr gesunken, erst auf 1200, dann auf 1080.
Rolf M. schrieb:> Seitdem> ist die (eigentlich besonders wichtige) vertikale Auflösung leider immer> mehr gesunken, erst auf 1200, dann auf 1080.
Es gibt auch Monitore mit 2560x1440, 2560x1600 oder 2048x2048 zu kaufen.
Man kann Monitore üblicherweise vertikal betreiben (nur bei TN-Panels
macht das keine Freude).
Dr. Sommer schrieb:> wenn man ständig hin und her gucken muss um die richtige> Stelle zu sehen, weil alles so elendig ausgedehnt ist
Ich weiss ja nicht, was Du so schreibst, aber meine Programme haben
durchaus mal mehrere 1.000 bis 10.000 Zeilen. Da ist es völlig egal, ob
ich die auf die Hälfte eindampfen könnte, die kann man trotzdem nicht
mit einem Blick übersehen.
Da hilft eine vernünftige Aufteilung in Includes / Units, knackige
Prozeduren und eine ordentliche Unterstützung durch die IDE mittels
Codebrowser, Codefaltung...
Abradolf L. schrieb:> Man kann Monitore üblicherweise vertikal betreiben (nur bei TN-Panels> macht das keine Freude).
Was erwartest Du? Der homo novus braucht für Videos im Querformat (für
Juniors: Landscape) zwingend eine Videokamera, weil er schlicht zu
dämlich ist, das Smartphone um 90 Grad zu drehen. Am anderen Ende kann
es nicht besser hinhauen.
Warum jemand mehr als 200 Codezeilen gleichzeitig auf dem Bildschirm
haben will, verstehe ich ohnehin nicht.
Rolf M. schrieb:> Was sich manch einer so aus der Benutzung> eines Operators heraus so zusammenphantasiert,> ist schon beeindruckend.
Nun ja... wohl weniger aus der Benutzung selbst
als aus den herabsetzenden Argumenten, mit denen
die Benutzung erbittert verteidigt wird.
Percy N. schrieb:> Warum jemand mehr als 200 Codezeilen gleichzeitig auf dem Bildschirm> haben will, verstehe ich ohnehin nicht.
200? Wenn ich bei HD und den üblichen Fenstern der IDE auf die Hälfte
komme, wäre das viel/klein.
Karl K. schrieb:> Ich weiss ja nicht, was Du so schreibst, aber meine Programme haben> durchaus mal mehrere 1.000 bis 10.000 Zeilen. Da ist es völlig egal, ob> ich die auf die Hälfte eindampfen könnte
Richtig. Bei so kleinen Programmen kommt es nicht so drauf an, zur Not
scrollt man ein wenig. Du hast bei 10.000 Zeilen halt 20-30 Files mit
20-30 Funktionen je 20-30 Zeilen. Wenn deine Projekte größer werden (x10
oder x100) kannst Du nur dann einfach entsprechend mehr Files nehmen,
wenn die Einzelteile unabhängig sind, z.b. Treiber oder
Funktionssammlung. Wenn die SW größer wird, weil die Aufgabe komplexer
wird (und nicht einfach nur mehr), dann werden Funktionen deutlich
länger und (kompakte, klare, schnörkellose) Lesbarkeit wichtiger.
Karl K. schrieb:> Da ist es völlig egal, ob ich die auf die Hälfte eindampfen könnte, die> kann man trotzdem nicht mit einem Blick übersehen.>> Da hilft eine vernünftige Aufteilung in Includes / Units, knackige> Prozeduren und eine ordentliche Unterstützung durch die IDE mittels> Codebrowser, Codefaltung...
Genau, und da man meistens nicht das ganze Programm gleichzeitig
bearbeitet sondern nur 1 Modul, Klasse, Datei ist es nett diese auf
einen Blick erfassen zu können. Wofür diese natürlich nicht zu groß
werden sollten, was sowieso nach schlechtem Design riecht.
Achim S. schrieb:> dann werden Funktionen deutlich länger
Wobei das verdächtig ist. Idealerweise hat man viele kleine Funktionen,
durch deren Kombination man alles erreichen kann; ggf. eben mit weiteren
Funktionen dazwischen, die immer einen klar definierten Zweck haben.
Egon D. schrieb:> Rolf M. schrieb:>>> Was sich manch einer so aus der Benutzung>> eines Operators heraus so zusammenphantasiert,>> ist schon beeindruckend.>> Nun ja... wohl weniger aus der Benutzung selbst> als aus den herabsetzenden Argumenten, mit denen> die Benutzung erbittert verteidigt wird.
Wenn die Benutzung nicht verbittert angegriffen würde, bräuchte sie auch
nicht verteidigt werden.
Sowohl das Dekrementieren / Inkrementieren als auch die bedingte
Zuweisung sind sinnvolle Funktionen. Dass sie von einigen nicht richtig
verstanden werden, ist deren Problem.
Jobst Q. schrieb:> Sowohl das Dekrementieren / Inkrementieren als auch die bedingte> Zuweisung sind sinnvolle Funktionen.
Erstens geht es nicht ums Dekrementieren / Inkrementieren, zweitens geht
es auch nicht darum, dass irgendjemand Verständnisprobleme damit hätte.
Jobst Q. schrieb:> Dass sie von einigen nicht richtig> verstanden werden, ist deren Problem.
Du kannst ja noch nicht mal verstehend lesen, also solltest du ganz
unten in der Hackordnung eher mal die Füße still halten, wenn Profis
sich unterhalten. Sobald du lesen gelernt hast, darfst mitmachen.
Percy N. schrieb:>> Man kann Monitore üblicherweise vertikal betreiben (nur bei TN-Panels>> macht das keine Freude).>> Was erwartest Du? Der homo novus braucht für Videos im Querformat (für> Juniors: Landscape) zwingend eine Videokamera, weil er schlicht zu> dämlich ist, das Smartphone um 90 Grad zu drehen. Am anderen Ende kann> es nicht besser hinhauen.
Das Thema wenn ältere Videokonsumenten nur Breitbildkonsum gelernt haben
und ihre Video-Versorgungsprobleme im für sie kompatiblen Format sogar
im Forum "PC-Programmierung" berichten müssen, wird im passenderen
OT-Bereich Beitrag "Fernsehbild rechts und links verspiegelt"
bereits erläutert.
Wenn du an deinem Ende des Empfangs auf Landscape angewiesen bist, dann
kann u.U. das in der Serie von ähnlich Betroffenen genutzte
Kompatibilitätsprogramm Taff "hoch ist das neue quer" helfen.
"
{
}
"
sind in Landscape sicherlich viele Informationen.
Egon D. schrieb:>> Man fragt sich echt immer wieder, warum manche so>> ein massives Problem damit haben, leserlichen Code>> zu schreiben.>> Mehrere Möglichkeiten:>> 1. Sie haben kein sicheres Gefühl dafür, wie guter,> leserlicher Code aussieht.>> 2. Ihnen fehlt die auf Erfahrung beruhende Einsicht,> dass man nicht nur für den Compiler schreibt,> sondern auch für den Menschen, der den Code in> einer Woche, einem Monat oder einem Jahr nochmal> anfassen muss.>> 3. Sie verwechseln "gut programmieren können" mit> "sämtliche schmutzigen Tricks kennen, die der> Compiler gerade noch durchgehen lässt".>> 4. Sie glauben TATSÄCHLICH, Mikrooptimierung führe> zu besseren Programmen.
Da gibt es noch nen Punkt:
5. Sie haben seit langer Zeit keine andere Programmiersprache als C
(oder C++) benutzt. Das schränkt den geistigen Horizont ein und
verstärkt dadurch den genannten Punkt 3 ganz massiv: üble Tricks zu
benutzen, kommt ihnen deshalb als das Natürlichste der Welt vor und sie
können es einfach nicht mehr verstehen, daß Andere ihre Trickserei
monieren.
Dieser Punkt fällt mir - der ich sowohl in Pascal als auch in C
programmiere - bei vielen besonders fanatisch argumentierenden C-Leuten
hier in diesem Forum besonders stark auf. Sie wollen nicht bieder,
defensiv, gutbürgerlich - oder wie man das auch nennen mag -
programmieren, weil sie genau das eben nicht mehr einzusehen vermögen.
Mir kommt da immer wieder olle Adenauer's Spruch vom Horizont in den
Sinn. Der alte Mann hatte es auf den Punkt gebracht:
https://www.zitate-online.de/sprueche/politiker/144/wir-leben-alle-unter-dem-gleichen-himmel.html
W.S.
mh schrieb:> Ich denke nicht sehr oft darüber nach, was der Compiler aus meinem> Quelltext machen soll. Ich gehe davon aus, dass der Compiler in 99% der> Fälle bessern Quelltext erzeugt, als ich.
Ja, dem kann ich mich nur anschließen:
Du denkst nicht sehr oft nach und beweist es sogleich dadurch, daß du
schreibst, daß der Compiler besseren QUELLTEXT schriebe als du. Exakt
diesen Punkt glaube ich dir vollkommen.
Eigentlich ist es der Job des Compilers, den Quelltext zu lesen und
daraus Maschinencode zu erzeugen. Das Schreiben eines Quelltextes ist
Aufgabe des Programmierers, gelle?
Aber du denkst ja nicht sehr oft...
W.S.
W.S. schrieb:> 5. Sie haben seit langer Zeit keine andere Programmiersprache als C> (oder C++) benutzt. Das schränkt den geistigen Horizont ein und> verstärkt dadurch den genannten Punkt 3 ganz massiv: üble Tricks zu> benutzen,
Wie bereits erwähnt ist die gezeigte Nutzung des ?:-Operators an
funktionale Sprachen angelehnt, und daher eben kein übler Trick, sondern
eher ein (eingeschränktes) Übernehmen von sinnvollen Paradigmen. In
Haskell sieht die Fakultät z.B. so aus:
1
factorial n = if n == 0 then 1 else n * factorial (n - 1)
Wenn man jetzt das if-else durch ?: ersetzt ist man der C(++)-Variante
schon näher. If-else kann man in C(++) ja leider so nicht nutzen, weil
es keinen Rückgabewert hat.
Achim S. schrieb:> Wenn die SW größer wird, weil die Aufgabe komplexer> wird (und nicht einfach nur mehr), dann werden Funktionen deutlich> länger und (kompakte, klare, schnörkellose) Lesbarkeit wichtiger.
Komische Schlussfolgerungen. Warum sollten kürzere Programme nicht
ebenso komplexe Prozeduren beinhalten?
Wer zwingt Dich, bei längeren Programmen auch die Prozeduren länger zu
machen?
Mir kommt das eher so vor, als würdest Du krampfhaft "Argumente" suchen,
um schlechten Code zu rechtfertigen.
Naja, nicht mein Problem, ich werde Deinen Code wahrscheinlich nie lesen
müssen.
Dr. Sommer schrieb:> If-else kann man in C(++) ja leider so nicht nutzen, weil> es keinen Rückgabewert hat.
"Leider"? - na wenigstens ein winziger Fortschritt ggü C - ich würde
eher sagen "endlich".
Bedenke mal, was für Unmengen von Fehlern in den Jahren seit Bestehen
von C durch if(a=b) verzapft worden sind. Nicht ohne Grund meckert
heutzutage eigentlich JEDER C-Cpmpiler über dieses.
W.S.
Jobst Q. schrieb:> Egon D. schrieb:>> Rolf M. schrieb:>>>>> Was sich manch einer so aus der Benutzung>>> eines Operators heraus so zusammenphantasiert,>>> ist schon beeindruckend.>>>> Nun ja... wohl weniger aus der Benutzung selbst>> als aus den herabsetzenden Argumenten, mit denen>> die Benutzung erbittert verteidigt wird.>> Wenn die Benutzung nicht verbittert angegriffen> würde, bräuchte sie auch nicht verteidigt werden.
Das ist ein logischer Kurzschluss.
Man ist NICHT verpflichtet, reflexhaft alles zu ver-
teidigen, was kritisiert wird -- man darf die Argumente
der Kritiker auch prüfen und ihnen gegebenenfalls
zustimmen.
> Sowohl das Dekrementieren / Inkrementieren als auch> die bedingte Zuweisung sind sinnvolle Funktionen.
Zumindest für Inkrement/Dekrement bin ich nicht Deiner
Meinung. 1970 mag das sinnvoll gewesen sein, weil man
so den Compiler dazu bringen konnte, den entsprechenden
Assemblerbefehl zu verwenden -- aber 2018 sind
optimierende Compiler die Regel, da bringt das nicht
mehr viel.
Der Nachteil, dass man auf diese Art Ausdrücke mit
Seiteneffekt konstruiert, bleibt aber erhalten -- und
der ist in meinen Augen entscheidend.
> Dass sie von einigen nicht richtig verstanden werden,> ist deren Problem.
Ebenfalls ein Kurzschluss. Es könnte doch auch sein,
dass sie es sehr wohl verstanden haben -- aber ganz
einfach anderer Meinung sind als Du?
W.S. schrieb:> "Leider"? - na wenigstens ein winziger Fortschritt ggü C - ich würde> eher sagen "endlich".
Hast du gelesen was ich geschrieben habe? Es wäre schön wenn so etwas
ginge:
1
intfactorial(intn){
2
returnif(n==1)
3
1;
4
else
5
factorial(n-1)*n;
6
}
genau wie es in Haskell, ruby, Scala, LISP, ... auch geht. Am Besten
noch ohne das "return", und nimmt den letzten Ausdruck der Funktion als
Rückgabewert. Aber leider kann C und C++ das eben nicht, weshalb man
sich mit ?: behilft:
1
intfactorial(intn){
2
returnn==1?
3
0
4
:
5
factorial(n-1)*n;
6
}
Was das jetzt mit dem Zuweisungsoperator zu tun haben soll verstehe ich
auch nicht.
Egon D. schrieb:> Der Nachteil, dass man auf diese Art Ausdrücke mit> Seiteneffekt konstruiert, bleibt aber erhalten -- und> der ist in meinen Augen entscheidend.
Und
Dr. Sommer schrieb:> Wie bereits erwähnt ist die gezeigte Nutzung> des ?:-Operators an funktionale Sprachen angelehnt,> und daher eben kein übler Trick,
Der Versuch, sich in einer Sprache so auszudrücken,
wie man sich in einer anderen Sprache ausdrücken
würde, ist (fast) immer ein übler Trick.
Schreibe ich etwa in kyrillischen Buchstaben und
verteidige das damit, dass deren Benutzung an die
russische Sprache angelehnt ist?
> In Haskell [...]
Ja -- dann verwende doch Haskell!
Aber hör' einfach damit auf, den Leuten, die möglichst
klar verständliches C programmieren wollen, damit auf
die Nüsse zu gehen, wie man dieses oder jenes in Haskell
machen würde!
Egon D. schrieb:> Der Versuch, sich in einer Sprache so auszudrücken,> wie man sich in einer anderen Sprache ausdrücken> würde, ist (fast) immer ein übler Trick.
Hat hier aber keinen Nachteil, außer der vermeintlichen
Nicht-Lesbarkeit. Wenn man das in anderen Sprachen lesen kann, kann man
das auch in C oder C++ lesen.
Egon D. schrieb:> Aber hör' einfach damit auf, den Leuten, die möglichst> klar verständliches C programmieren wollen, damit auf> die Nüsse zu gehen, wie man dieses oder jenes in Haskell> machen würde!
W.S. hat damit angefangen den ternären Operator zu verteufeln. Ich habe
dagegen argumentiert. Darf hier nur W.S. seine Meinung verbreiten?
Dr. Sommer schrieb:> Egon D. schrieb:>> Der Versuch, sich in einer Sprache so auszudrücken,>> wie man sich in einer anderen Sprache ausdrücken>> würde, ist (fast) immer ein übler Trick.>> Hat hier aber keinen Nachteil, außer der vermeintlichen> Nicht-Lesbarkeit. Wenn man das in anderen Sprachen lesen> kann, kann man das auch in C oder C++ lesen.
Ein überraschend deutliches Bekenntnis zur Unkollegialität.
Ich lasse das einfach mal ohne weitere Analyse so stehen.
> Egon D. schrieb:>> Aber hör' einfach damit auf, den Leuten, die möglichst>> klar verständliches C programmieren wollen, damit auf>> die Nüsse zu gehen, wie man dieses oder jenes in Haskell>> machen würde!>> W.S. hat damit angefangen den ternären Operator zu> verteufeln.
Nicht ganz: Er hat es IN DER PROGRAMMIERSPRACHE C
verteufelt.
> Ich habe dagegen argumentiert.
Ja -- indem Du andere Programmiersprachen als Beleg
dafür herangezogen hast, dass es eine Supersache ist.
> Darf hier nur W.S. seine Meinung verbreiten?
Überhaupt nicht. Aber genauso, wie Du in einer Diskussion
über C mit Deinen Haskell-Kenntnissen angeben darfst,
darf ich darauf antworten, dass mir das auf die Nüsse geht,
weil es um guten Stil in C geht -- und nicht um Haskell.
Egon D. schrieb:> Überhaupt nicht. Aber genauso, wie Du in einer Diskussion> über C mit Deinen Haskell-Kenntnissen angeben darfst,> darf ich darauf antworten, dass mir das auf die Nüsse geht,> weil es um guten Stil in C geht -- und nicht um Haskell.
Um dich zu beruhigen: Ich kann Haskell auch nicht.
Dann darf ich sagen, dass es mir auf die Nüsse geht, dass man hier
sofort angegangen wird, wenn man demonstriert dass es jenseits des
C-Tellerrands noch mehr gibt, und man auch noch als unkollegial
dargestellt wird, wenn man Techniken nutzt, die man nicht auf den ersten
7 Seiten von "C für Dummies" lernt.
Wenn man sich immer am allerkleinsten gemeinsamen Nenner orientiert und
nie mal was neues ausprobiert gibt's auch keinen Fortschritt. Und ja,
dazu gehört auch, gute Ideen aus anderen Sprachen zu übernehmen. Die
Mentalität "C ist die einzig valide Sprache und alles was danach
erfunden wurde interessiert mich nicht"-Mentalität geht mir auf die
Nerven. Wenn hier im Analog-Bereich jemand unbedingt ein antikes Bauteil
nutzen will, darf man ihn ja auch darauf hinweisen, dass vielleicht mal
etwas neues angesagt ist.
Dr. Sommer schrieb:> Dann darf ich sagen, dass es mir auf die Nüsse geht,> dass man hier sofort angegangen wird, wenn man> demonstriert dass es jenseits des C-Tellerrands noch> mehr gibt,
Es ging in der Diskussion primär darum, wie man mit
den Fallen und Beschränkungen von C am besten umgeht.
Da finde ich die ständig wiederholten Verweise auf
Lisp, Haskell, Scheme, ... ziemlich nervtötend.
> und man auch noch als unkollegial dargestellt wird,> wenn man Techniken nutzt, die man nicht auf den> ersten 7 Seiten von "C für Dummies" lernt.
Nein -- ich kritisiere nicht, dass Du diese Techniken
benutzt, sondern ich kritisiere, dass Du diejenigen,
die sie ablehnen, als Deppen hinstellst. Das ist genau
das, was ich als permanente Herabsetzung bezeichne, und
ich kann das bei Bedarf auch am geschriebenen Text
belegen.
> Wenn man sich immer am allerkleinsten gemeinsamen> Nenner orientiert und nie mal was neues ausprobiert> gibt's auch keinen Fortschritt.
Alles dort, wo es hingehört.
Wer C lernt, tut das i.d.R. nicht aus akademischem
Interesse, sondern aus der Notwendigkeit heraus, mit
anderen Leuten zusammen Probleme zu bearbeiten, die
sich aus irgendwelchen Gründen nur in C lösen lassen.
Hier ist es STARK anzuraten, sich an dem zu orientieren,
was fähige Leute als guten Stil ansehen.
Der penetrante Hinweis, dass ja Lisp/Scheme/Haskell/C++
viel schöner wäre, weil... ist einfach kontraproduktiv
und nervtötend.
> Und ja, dazu gehört auch, gute Ideen aus anderen> Sprachen zu übernehmen.
Ja -- wenn man eine neue Sprache entwickelt.
> Die Mentalität "C ist die einzig valide Sprache und> alles was danach erfunden wurde interessiert mich> nicht"-Mentalität geht mir auf die Nerven.
Du ahnst nicht einmal ansatzweise, wie weit Du damit
bei mir danebenliegst.
Für das, was ich schnell 'runterschreiben will,
verwende ich Tcl, und für das, was schnell ausgeführt
werden soll, in zunehmendem Maße Pascal.
C lerne ich nur gezwungenermaßen.
Und zum "funktionalen Paradigma" wiederhole ich, was
ich weiter oben schon schrieb: So lange die Bewohner
des Elfenbeinturms nicht lernen, zwischen parasitären
und problemimmanenten Zuständen zu unterscheiden, lohnt
es sich für mich nicht, ihre Theorien ernstzunehmen.
> Wenn hier im Analog-Bereich jemand unbedingt ein> antikes Bauteil nutzen will, darf man ihn ja auch> darauf hinweisen, dass vielleicht mal etwas neues> angesagt ist.
Wenn er eine existierende Steuerung mit TTL-ICs
reparieren muss, rätst Du ihm zu einer Soft-SPS auf
dem RaspberriPi? Ernsthaft?!
Egon D. schrieb:> Wer C lernt, tut das i.d.R. nicht aus akademischem> Interesse, sondern aus der Notwendigkeit heraus, mit> anderen Leuten zusammen Probleme zu bearbeiten, die> sich aus irgendwelchen Gründen nur in C lösen lassen.> Hier ist es STARK anzuraten, sich an dem zu orientieren,> was fähige Leute als guten Stil ansehen.
[Whataboutism]
Der Linux Kernel ist also von unfähigen C Programmierer geschrieben, da
er voll von ? ist. ;)
[\Whataboutism]
Vincent H. schrieb:> Der Linux Kernel ist also von unfähigen> C Programmierer geschrieben, da er voll> von ? ist. ;)
Hmm. Ich weiss nicht. Vielleicht ist "fähiger
C-Programmierer" sowieso ein schwarzer Schimmel...
SCNR
Dr. Sommer schrieb:> W.S. hat damit angefangen den ternären Operator zu verteufeln. Ich habe> dagegen argumentiert. Darf hier nur W.S. seine Meinung verbreiten?
Muhaha! Und schon sind wir wieder im Kindergarten angekommen. Bzw. haben
das übliche Forumsniveau erreicht.
Köstlich!
Egon D. schrieb:> Da finde ich die ständig wiederholten Verweise auf> Lisp, Haskell, Scheme, ... ziemlich nervtötend.
Ich finde deine Abneigung gegen funktionale Sprachen nervtötend.
Egon D. schrieb:> Nein -- ich kritisiere nicht, dass Du diese Techniken> benutzt, sondern ich kritisiere, dass Du diejenigen,> die sie ablehnen, als Deppen hinstellst.
Ich habe niemanden als Deppen bezeichnet. Du kommst mit Begriffen wie
"unkollegial".
Egon D. schrieb:> Der penetrante Hinweis, dass ja Lisp/Scheme/Haskell/C++> viel schöner wäre, weil... ist einfach kontraproduktiv> und nervtötend.
Dann lies es nicht, bzw. argumentier nicht dagegen...
Egon D. schrieb:> Ja -- wenn man eine neue Sprache entwickelt.
Auch nach der Entwicklung einer Sprache kann man noch Verbesserungen
am Programmierstil machen. Ist in C++ nicht anders.
Egon D. schrieb:> C lerne ich nur gezwungenermaßen.
Wer zwingt dich?
Egon D. schrieb:> So lange die Bewohner> des Elfenbeinturms nicht lernen, zwischen parasitären> und problemimmanenten Zuständen zu unterscheiden, lohnt> es sich für mich nicht, ihre Theorien ernstzunehmen.
Kannst du mal etwas ausführen, was du für ein anscheinend fundamentales
Manko am funktionalen Paradigma gefunden hast, welches immerhin von
Kapazitäten im akademischen Bereich befürwortet wird?
Egon D. schrieb:> Wenn er eine existierende Steuerung mit TTL-ICs> reparieren muss, rätst Du ihm zu einer Soft-SPS auf> dem RaspberriPi? Ernsthaft?!
Das habe ich nicht. Aber wie wär's mit einem CPLD?
Karl K. schrieb:> Muhaha! Und schon sind wir wieder im Kindergarten angekommen. Bzw. haben> das übliche Forumsniveau erreicht.
Ah, diskutieren ist im Diskussionsforum also verboten? Jede Meinung soll
so stehen bleiben?
Karl K. schrieb:> "Mimimi, W.S. hat angefangen" ist keine Diskussion, das ist> Kindergarten.
Was ist denn deiner Meinung nach ein valider Grund, eine Meinung zu
schreiben, wenn nicht, dass jemand eine gegenteilige geschrieben hat?
Soll jeder für jede Aussage einen neuen Thread aufmachen, seine Meinung
schreiben, aber Antworten ist verboten?
Dr. Sommer schrieb:> Egon D. schrieb:>> Da finde ich die ständig wiederholten Verweise auf>> Lisp, Haskell, Scheme, ... ziemlich nervtötend.>> Ich finde deine Abneigung gegen funktionale Sprachen> nervtötend.
Das ist sachlich unmöglich, weil ich keine Abneigung
gegen funktionale Sprachen habe.
Ich habe eine Abneigung gegen Deine NERVTÖTENDENES
MISSIONIEREN -- weil es in der laufenden Diskussion
um C geht.
> Egon D. schrieb:>> Nein -- ich kritisiere nicht, dass Du diese Techniken>> benutzt, sondern ich kritisiere, dass Du diejenigen,>> die sie ablehnen, als Deppen hinstellst.>> Ich habe niemanden als Deppen bezeichnet.
Damit ist gemeint: Du setzt permanent Leute herab, die
anderer Meinung sind als Du.
Du sprichst beispielsweise davon, dass XYZ "für
professionelle Programmierer kein Problem" sei, und
unterstellst damit, dass Leute, die das anders sehen,
unprofessionell sind.
Du sprichst von "vermeintlicher Nicht-Lesbarkeit" und
unterstellst damit, dass Du natürlich zuverlässig weisst,
was lesbar und was unlesbar ist, die anderen aber nicht.
Du sprichst davon, dass, wer X in anderen Sprachen könne,
es auch in C oder C++ beherrsche -- dass Programmierer,
die im wesentlichen nur C machen, deswegen weder dumm
noch unprofessionell sein müssen, kommt in Deinem
Universum offenbar nicht vor.
> Du kommst mit Begriffen wie "unkollegial".
Ja, und dabei bleibe ich.
> Egon D. schrieb:>> Der penetrante Hinweis, dass ja Lisp/Scheme/Haskell/C++>> viel schöner wäre, weil... ist einfach kontraproduktiv>> und nervtötend.> Dann lies es nicht, bzw. argumentier nicht dagegen...
Aber doch.
Es ist einfach eine Frage der Höflichkeit, dass man nicht
JEDEN C-Thread mit C++ oder Scheme zuspammt. Wenn Dir das
nicht von selbst einleuchtet, muss man Dich eben daraufhin-
weisen und hoffen, dass es IRGENDWANN ankommt.
Karl K. schrieb:> Achim S. schrieb:>> Wenn die SW größer wird, weil die Aufgabe komplexer>> wird (und nicht einfach nur mehr), dann werden Funktionen deutlich>> länger und (kompakte, klare, schnörkellose) Lesbarkeit wichtiger.>> Komische Schlussfolgerungen. Warum sollten kürzere Programme nicht> ebenso komplexe Prozeduren beinhalten?
Komplexe Prozeduren sind nicht das Problem, sondern komplexe
(Gesamt-)Aufgaben.
sin() ist relativ komplex, auch sqrt. Da die Funktionen aber keinerlei
Seiteneffekte haben, nur einen Ein- und Ausgabewert, steigern sie nicht
die Gesamt-Komplexität. 1000 Funktionen dieser Art in einer
Tool-Sammlung heisst einfach nur 1000x die Arbeit einer Funktion.
Hast Du hingegen ein (emergentes) Projekt, in dem 5 viel einfacherer
binäre Statusmaschinen irgendwie interaggieren müssen, steigt die
Gesamtkomplexität auf einmal weit höher als die Tool-Sammlung oben. Und
da hilft auch keine Dokumentation mehr.
sin() und sqrt() sind einfach zu beschreiben, weil sie wohlbekannte
Funktionalitäten liefern. Es reicht eine Seite, welche Klassen von
Eingaben mit welcher (mindest-)Genauigkeit welche Ausgaben liefern.
--> Die Doku kann klein sein gegenüber der Implementierung, oder wie
Brooks (vom Mythischen Mannmonat) sagen würde: Hoher Anteil Akzidenz.
sobald aber ein paar einfache Funktionen interagieren, wird die
Dokumentation ähnlich komplex wie die Beschreibung. Da Beschreibung
(Word, Charts, UML) in vielen Bereichen weniger Ausdrucksstark ist, kann
es sogar sein, dass die Beschreibung komplexer wäre als der Code.
Nämlich dann, wenn dieser hauptsächlich Essenz ist.
--> Dann hast Du den Fall, wo der Code das Modell ist, und
zugeschnittene Dokumente (Tester, Nutzer, Zulasser, Marketing, ...) vom
Code abgeleitet werden. Wo der Code das Original ist (und nicht ein
gemaltes UML-Modell), wo der Code (also die strategischen Teile, nicht
Gui-Malerei oder Parameterverwaltung, Du weiss was ich meine) so lesbar
sein muss wie komplexe mathematische Formeln. Nicht für Anfänger, nicht
für Endkunden, sondern für Kollegen und Fachleute, also erfahrende
SW-Entwickler (oder hier: Mathematiker).