hier Mal meine Version des obigen Codes (Tippfehler incl.)
das while (1) zeigt gut dass hier eine Endlosschleife droht
int portIsInList( PCB *pcb, PORT port )
{
for( ; pcb != NULL; pcb = pcb->next)
if (pcb->local_port == port)
return true;
return false;
}
while ( 1 )
{
if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
port = TCP_LOCAL_PORT_RANGE_START;
}
/* Check all PCB lists. */
for (i = 0; i < NUM_TCP_PCB_LISTS; i++)
if ( portIsInList(*tcp_pcb_lists[i], port)
break;
if ( i == NUM_TCP_PCB_LISTS )
return port;
}
>> wie schon geschrieben>> Wenn bsp.weise in mehreren Else-Zweigen die Gleiche (Fehler oder>> Sonstige)Behandlung durchgeführt werden soll.>> Das geht Nicht ohne Umwege!>Dann hat man einen Fehler bzw. eine Schwachstelle im Software-Design:
Oder dein Design ist zu billig.
Man kann nämlich nicht ausschliessen, dass im Programm mehrere
Überprüfungen (betr. eines Sachverhalts) gemacht werden sollen, die im
Nicht-Erfolgs-Falle in einer gemeinsamen Behandlung münden.
@ Walter S. (avatar)
>mehr überblickt habe, muss ich leider sagen dass diese Umsetzung>fehlerhaft ist:>wenn die innerste Schleife mit>pcb == NULL>abbricht und dann zu>if (pcb->local_port == port)>kommt gibt es einen Fehler.
Hmm, stimmt.
> Richtig wäre stattdessen>if ( pcb!=NULL )>entsprechend beim while>i < NUM_TCP_PCB_LISTS
Hmm.
>hier Mal meine Version des obigen Codes (Tippfehler incl.)>das while (1) zeigt gut dass hier eine Endlosschleife droht
Auch die ist nicht korrekt ;-)
Und ich mag keine Schleifen mit nur einer Anweisung ohne Klammern.
> if ( i == NUM_TCP_PCB_LISTS )> return port;> }
Und welchen Rückgabewert gibt es, wenn die Bedingung NICHT erfüllt ist?
Aber der Ansatz mit dem Zerlegen in Teilfunktionen ist deutlich besser!
Genau SO macht man das!
Aber ich muß gestehen, daß ich den Sinn dieses Programmabschnitts noch
nicht so ganz verstehe.
Es gibt ein Array pcb, welches Pointer auf verkettete Listen enthält
(äußere Schleife). In der inneren Scheilfe wird nach einem Eintrag
gesucht, welcher == port ist. Ist dieser gefunden, wird der port erhöht?
Nur wenn alle verketteten Listen durchsucht wurden und KEIN port
gefunden wurde, wird port zurückgegeben? Also ist die Funktion "Suche
den Port, der NIRGENDWO enthalten ist"? Ich kenne den Gesamtzusammenhang
hier nicht, aber ich denke, daß dort auch ein definiertes
Abbruchkriterium fehlt, den im Extremfall wird das eine Endlosschleife,
wenn JEDER mögliche Port immer gefunden wird, auch wenn das extrem
selten ist.
Also besser so. Und siehe da, es ist genau so kompakt wie die
goto-Variante und definitv OHNE Gefahr einer Endlosschleife! Es geht
auch ohne Funktion zum Durchsuchern der verketteten Liste.
Daniel A. schrieb:> Ich bin dafür, sofern es den Code vereinfacht, lesbarer macht und nicht> zu oft verwendet wird.> Falk Brunner ist dagegen, sofern es nicht sinvoll oder notwendig ist?> Mark Brandis ist dagegen, wenn immer es ohne geht oder es von einem> Anfänger benutzt wird?> W.S. scheint für goto zu sein?> Zeno sympathisiert mit W.S. ?>> Habe ich das so richtig im Kopf?
Alles korrekt in der Birne. Hatte in dem Post ja auch nicht Dich
angesprochen. Sieh Dir doch nur an wie man sich zwischenzeitlich schon
ein ein paar Zeilen Code aufgeilt. Langsam wird es peinlich.
Programmierer schrieb:> Im Prinzip ist es einfach: Wer "goto" verteidigt und nicht missbilligt,> muss noch ein paar Sprossen die Leiter der Erkenntnis nach oben> klettern.
Glückwunsch! Du scheinst ganz oben auf der Leiter zu stehen. Aber
Vorsicht noch ein Schritt, dann bist Du auch ganz schnell wieder unten.
nichtCler schrieb:> Noch furchtbarer als meine Kommentare? Das macht mir Angst und stelle> deshalb das Schreiben in diesem thread ein.
Ach Du darfst ruhig weiter schreiben. Wir machen doch alle Fehler - gilt
auch bei Rechtschreibung.
M. K. schrieb:> Durchs Knie ins Auge schießen kann man in C nicht nur mit goto, das geht> mit allen Schleifen prima.
Geht in allen Programmiersprachen.
sepp schrieb:> Wie du in deinem Beitrag selbst schon schreibst ist es wichtig gut> strukturierte Software zu schreiben und du zeigst ja auch das man ohne> goto einiges falsch machen kann. Goto kann falsch angewendet, schnell zu> schlecht strukturierter Code führen aber in einigen Fällen auch sehr> hilfreich sein um gut strukturierten Code zu erzeugen.
Richtig! Ist halt immer wieder schön wenn jemand heraus findet, das sich
ein selbst ernannter Gott mal wieder klassisch ins Knie gebohrt hat.
Mark B. schrieb:> Die bisherigen Beispiele sind kein Beweis, denn sie sind entweder> unvollständig oder verstoßen gegen Best Practice-Regeln des Software> Designs oder beides.
Da Du generell gegen die Verwendung von goto bist, wird sich kein Code
mit goto finden lassen der Deinen sturen Ansichten genügt.
@MCUA, @blablablubb : Laßt es! Mark weiß es immer besser, es gilt nur
seine Meinung. Das Beste wird wohl sein Burschen links liegen zu lassen.
Mikro 7. schrieb:> In den Referenzen findet man dann auch u.a. Linus' Statement dazu:>> I think goto's are fine
Schau in den Folgepost und Du wirst sehen auch hierzu hat Mark ein
Statement - er weis es natürlich besser. Aber jetzt scheinen ihm langsam
die Argumente auszugehen und deshalb muß jetzt dies
Mark B. schrieb:> Linus Torvalds hat nie ein Buch über Software-Design geschrieben. Oder> über Software-Architektur. Oder darüber, wie man Software richtig> testet.
herhalten. Linus T. ist ja auch nur so ein Dau der von nichts eine
Ahnung hat.
Mark B. schrieb:> Warum wohl? ;-)
Er ist ja der Vater des Linuxkerns und das ist BS und das ist ja nach
Ansicht einige Leute hier auch was ganz anders.
Allerdings zeugt Linus's Äußerung zu Pascal und zu seinem Erfinder
Niklaus Wirth auch nicht von guter Kinderstube. Niklaus Wirth war
sicherlich nicht geistig unterbelichtet.
Zeno
Falk B. schrieb:> Also ist die Funktion "Suche> den Port, der NIRGENDWO enthalten ist"?
Wenn man in TCP eine neue Verbindung zu einem anderen Host herstellen
will, muss man zuerst ein noch nicht benutztes source/destination
address pair suchen. Da dieser Code, sofern nicht jede destination
address eigene tcp_pcb_lists hat, die destination addresse ignoriert,
kann man das System Lahmlegen indem man es dazu bringt 2^16-1
Verbindungen herzustellen, falls dies vom restlichen Code her überhaupt
möglich ist.
Als Rückgabe wert im falle eines Fehlers wäre hier 0 geeignet, da dieser
Port ansonsten nicht verwendet werden darf.
Falk B. schrieb:> Und jetzt werden die Goto-ianer wieder über die Hilfsvariable found> lästern ;-)
Nö warum? Eine Hilfsvariable kann doch durchaus Sinn machen unabhängig
von while, for, goto etc.
Falk B. schrieb:> Aber ich muß gestehen, daß ich den Sinn dieses Programmabschnitts noch> nicht so ganz verstehe.
Ich sagte doch, das ich das Beispiel willkürlich aus den Sourcen
herausgegriffen habe. Irgendwie geht es in der Gesamtdatei um den TCP
Stack. Aber wirklich kann ich das nicht beurteilen und würde es mir auch
nicht anmaßen. Da hilft nur eins selbst die Quellen anschauen.
@ Daniel Abrecht (daniel-a)
>kann man das System Lahmlegen indem man es dazu bringt 2^16-1>Verbindungen herzustellen, falls dies vom restlichen Code her überhaupt>möglich ist.
Diverse Sicherheitslecks und andere Bugs basieren auf so etwas.
Solider, bombenfester Code vermeidet sowas sicher.
Mark B. schrieb:> Dann zeig mir eins. Ein Beispiel mit goto, wo man keine andere> Unterteilung des Codes in Funktionen, kein anderes Software Design hätte> wählen können, das besser gewesen wäre.
Das habe ich bewusst nicht getan und werde es auch nicht tun. Und das
hat zwei Gründe:
- Es wurde schon oft genug getan.
- Du wirst dir eine "schönere" Lösung mit Hilfsvariablen und Splittung
in Funktionen aus den Fingern saugen, die in Wirklichkeit nicht schöner
ist, sondern nur dazu dient dir ein gutes Gefühl zu geben.
blablablubb schrieb:> Mark B. schrieb:>> Dann zeig mir eins. Ein Beispiel mit goto, wo man keine andere>> Unterteilung des Codes in Funktionen, kein anderes Software Design hätte>> wählen können, das besser gewesen wäre.>> Das habe ich bewusst nicht getan und werde es auch nicht tun. Und das> hat zwei Gründe:> - Es wurde schon oft genug getan.> - Du wirst dir eine "schönere" Lösung mit Hilfsvariablen und Splittung> in Funktionen aus den Fingern saugen, die in Wirklichkeit nicht schöner> ist, sondern nur dazu dient dir ein gutes Gefühl zu geben.
Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so
besser ist wie ich es beschreibe.
Wen eine bessere Modularität und eine bessere Testbarkeit des Codes
nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die
Sintflut" Programmierer. "Wozu Unit Tests? Mein Code funktioniert auch
so!"
Kenne ich, habe ich schon diverse Kollegen gehabt die so arbeiten. Die
meisten von ihnen sind zum Glück nicht mehr da. Qualität setzt sich
irgendwann eben doch durch, bzw. Mangel an Qualität fliegt raus.
Mark B. schrieb:> Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so> besser ist wie ich es beschreibe.
Die Argumente für goto sind älter als das Internet und wurden schon
millionenfach genannt. Das braucht man nicht mehr zu wiederholen.
> Wen eine bessere Modularität und eine bessere Testbarkeit des Codes> nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die> Sintflut" Programmierer. "Wozu Unit Tests? Mein Code funktioniert auch> so!"
Es ist doch völlig absurd zu behaupten der Code würde irgendwie magisch
besser testbar, wenn man kein goto verwendet.
Um es mit Linus' Worten zu sagen: Only a moron would believe that.
blablablubb schrieb:> Es ist doch völlig absurd zu behaupten der Code würde irgendwie magisch> besser testbar, wenn man kein goto verwendet.
Das hat auch keiner so behauptet. Lerne lesen und Zusammenhänge
verstehen, dann komm wieder.
Mark B. schrieb:> Das hat auch keiner so behauptet.
Doch das hast du. Zitat:
>Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so>besser ist wie ich es beschreibe.>Wen eine bessere Modularität und eine bessere Testbarkeit des Codes>nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die>Sintflut" Programmierer.
Und jetzt höre auf zu lügen.
Noch einmal zu dem von Zeno geposteten Beispielcode aus lwIP:
Ein Rückwärts-Goto ist böser als ein Vorwärts-Goto, da er eine Schleife
kaschiert. Für Schleifen stellt C aber genügend Konstrukte zur Auswahl
(for, while, do), von denen praktisch immer eines passend ist.
Und die Prüfung, ob der jeweils betrachtete Port schon benutzt wird,
schreit gerade danach, in eine eigene Funktion ausgelagert zu werden.
Deswegen sähe mein Vorschlag so aus:
Die Funktion port_is_in_use enthält zwar immer noch einen verkappten
Goto, nämlich die Return-Anweisung inmitten der inneren Schleife. Zum
einen ist das aber ein Vorwärtssprung, der nicht ganz so böse ist, zum
anderen ist die Funktion so kurz, dass trotz dieses Schönheitsfehlers
ihre Ablaufstruktur mit einem Blick erfasst werden kann.
Man könnte natürlich die innere Schleife in eine weitere Funktion
auslagern und käme dann mit jeweils einem Break als Schleifenabbruch
aus. Bei dieser kurzen Funktion halte ich es aber für übertrieben, sie
weiter aufzuteilen.
Welche der drei Versionen (Original, von Falk und die obige) am besten
lesbar ist, muss jeder subjektiv für sich entscheiden.
Effizienz ist in diesem Fall übrigens kein Argument für den Goto im
Originalcode, denn der GCC erzeugt aus dem obigen Quelltext
erwartungsgemäß den gleichen Assemblercode.
Hier ist der Vollständigkeit halber noch der Kommentar über dem
Originalcode dieser Funktion:
1
/*
2
* tcp_new_port():
3
*
4
* A nastly hack featuring 'goto' statements that allocates a
Mark B. schrieb:> Wen eine bessere Modularität und eine bessere Testbarkeit des Codes> nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die> Sintflut" Programmierer. "Wozu Unit Tests? Mein Code funktioniert auch> so!">> Kenne ich, habe ich schon diverse Kollegen gehabt die so arbeiten. Die> meisten von ihnen sind zum Glück nicht mehr da. Qualität setzt sich> irgendwann eben doch durch, bzw. Mangel an Qualität fliegt raus.
Unit Tests ist kein Garant für fehlerfreien Code, denn den Testfall
generiert der Programmierer und wenn der einen Fehler in seinem
Denkansatz hat, dann geht es halt in die Hose.
Zeno schrieb:> Unit Tests ist kein Garant für fehlerfreien Code
Nicht unbedingt. Es ist häufig unrealistisch jeden möglichen Ausgabewert
zu jedem möglichen Eingabewert zu überprüfen. Es kann durchaus
passieren, dass ein Fehler bei einem Spezialfall enthalten ist, den man
beim Testcase nict bedacht hatte oder nicht wissen konnte.
Yalu X. schrieb:> Welche der drei Versionen (Original, von Falk und die obige) am besten> lesbar ist, muss jeder subjektiv für sich entscheiden.
Genau so ist es.
>> Effizienz ist in diesem Fall übrigens kein Argument für den Goto im> Originalcode, denn der GCC erzeugt aus dem obigen Quelltext> erwartungsgemäß den gleichen Assemblercode.
Das vermag ich nicht zu beurteilen.
>> Hier ist der Vollständigkeit halber noch der Kommentar über dem> Originalcode dieser Funktion:
Endlich mal einer der nicht stur irgend etwas behauptet, sondern sich
die Mühe macht mal die Quellen des Codeschnipsels anzusehen und erst
dann sein Statement abgibt.
Zeno
Daniel A. schrieb:> Es ist häufig unrealistisch jeden möglichen Ausgabewert> zu jedem möglichen Eingabewert zu überprüfen. Es kann durchaus> passieren, dass ein Fehler bei einem Spezialfall enthalten ist, den man> beim Testcase nict bedacht hatte oder nicht wissen konnte.
Genau das habe ich doch geschrieben - halt anders formuliert.
Walter S. schrieb:> Falk B. schrieb:>> War noch ein kleiner Fehler drin 8-0>> So ist es richtig>> fast ;-)> i wird doppelt verwendet
Ist ja voll einfach, übersichtlich und elegant, so ein Quellcode ohne
goto.
blablablubb schrieb:> Mark B. schrieb:>> Das hat auch keiner so behauptet.>> Doch das hast du. Zitat:>>>Im Gegensatz zu Euch habe ich Argumente dafür genannt, warum es so>>besser ist wie ich es beschreibe.>>Wen eine bessere Modularität und eine bessere Testbarkeit des Codes>>nicht überzeugen, der ist wohl von der Mentalität der "Nach mir die>>Sintflut" Programmierer.>> Und jetzt höre auf zu lügen.
Erzähl doch keinen Käs.
Ich habe mehrere Male in diesem Thread gesagt, dass es in der Regel ein
schlechtes Software-Design ist, das zur Verwendung von goto führt. Wenn
man zu viel Code in eine einzelne Funktion hineinpackt, à la:
-Öffnen einer oder mehrer Ressource(n)
-Lesen von einer, oder Schreiben auf eine Ressource
-Behandlung von Fehlerfällen
-Schließen der Ressource(n)
dann kommt man leicht zu stark verschachteltem Code, wo man vielleicht
dann gerne mal dazu geneigt ist, mit goto "auszubrechen". Man muss das
Ganze aber nicht so aufziehen. Ein Refactoring führt zu besserem Code,
der stärker modularisiert ist. In einem solchen Code wird goto zu
99,999% überflüssig sein.
Natürlich steht es Dir frei, solche Argumente einfachb zu ignorieren,
wie Du es ja auch tust. Dann ist eine Diskussion freilich sinnlos.
Zeno schrieb:> Unit Tests ist kein Garant für fehlerfreien Code
Das ist schon richtig. Aber das hat auch niemand behauptet, dass dies
ein Garant wäre. Und deswegen...
> denn den Testfall> generiert der Programmierer und wenn der einen Fehler in seinem> Denkansatz hat, dann geht es halt in die Hose.
...gibt es nach dem Unit Test noch einen Integrationstest und/oder
entsprechend Regressionstests, die von jemand anderem als dem Entwickler
durchgeführt werden.
So üblich in der Medizintechnik, im Automotive-Bereich, Luft- und
Raumfahrt, Automatisierungstechnik, Schienenverkehrstechnik,
Analytischen Messtechnik, ...
@Yalu X. (yalu) (Moderator)
>Und die Prüfung, ob der jeweils betrachtete Port schon benutzt wird,>schreit gerade danach, in eine eigene Funktion ausgelagert zu werden.
Eben.
>Deswegen sähe mein Vorschlag so aus:>static bool port_is_in_use(u16_t port) {
Ist OK.
>static u16_t tcp_new_port(void) {> static u16_t port = TCP_LOCAL_PORT_RANGE_START;> do {> if (port++ >= TCP_LOCAL_PORT_RANGE_END)> port = TCP_LOCAL_PORT_RANGE_START;> } while(port_is_in_use(port));> return port;>}
Das hat wieder das Zeug zur Endlosschleife.
>/*> * tcp_new_port():> *> * A nastly hack featuring 'goto' statements that allocates a> * new TCP local port.> */
ERWISCHT!
;-)
Mark B. schrieb:> Erzähl doch keinen Käs.>> Ich habe mehrere Male in diesem Thread gesagt,>blabla
Das bestreite ich alles nicht. UND du hast gesagt, dass der Code besser
testbar ist, wenn kein goto verwendet wird. Und nur auf diese Aussage
bezog ich mich. Sie ist halt Unsinn.
Yalu X. schrieb:> Und die Prüfung, ob der jeweils betrachtete Port schon benutzt wird,> schreit gerade danach, in eine eigene Funktion ausgelagert zu werden.
@blablablubb
Da hast Du's. Wenn Du mir schon nicht glauben willst, dann glaub
wenigstens Yalu.
Mark B. schrieb:> ...gibt es nach dem Unit Test noch einen Integrationstest und/oder> entsprechend Regressionstests,>...
Und was hat das alles mit dem Thema zu tun?
Es geht hier um goto.
Mark B. schrieb:> Da hast Du's. Wenn Du mir schon nicht glauben willst, dann glaub> wenigstens Yalu.
Der Missbrauch von goto als Schleifenkonstrukt ist nicht schön. Das habe
ich nie bestritten.
Aber es gibt viele legitime Einsatzgebiete für goto. Diese wurden alle
schon genannt und sind trivial auffindbar.
blablablubb schrieb:> Das bestreite ich alles nicht. UND du hast gesagt, dass der Code besser> testbar ist, wenn kein goto verwendet wird.
Nein. Du verstehst "Ursache und Wirkung" nicht, kann das sein?
1.) Ursache: Schlechtes SW-Design - zu viel Code/zu viel Funktionalität
in einer Funktion
2.) Wirkung: Je nach Programmierer --> Unnötige Verwendung von goto,
oder anderweitig miese Code-Qualität
3.) Heilung: Besseres SW-Design --> Kleinere Funktionen, Weniger stark
verschachtelter Code, goto wird unnötig (falls es je nötig war ;-)
4.) Nebeneffekt: Kleinere Funktionen sind besser für Unit Tests.
Es ist nicht so schwer zu verstehen - wenn man mal drüber nachdenken
mag.
blablablubb schrieb:> Aber es gibt viele legitime Einsatzgebiete für goto. Diese wurden alle> schon genannt und sind trivial auffindbar.
Mit "viele" meinst Du sicher:
-Kernel Hacking unter Linux
-Kernel Hacking unter OpenBSD
-Kernel Hacking unter FreeBSD
-Kernel Hacking unter NetBSD
-Kernel Hacking unter blablablubb OS
;-)
Mark B. schrieb:> 1.) Ursache: zu viel Code/zu viel Funktionalität in einer Funktion> 2.) Wirkung: Unnötige Verwendung von goto,
Das ist doch an den Haaren herbeigezogener Mumpitz. Es besteht doch kein
Zusammenhang zwischen der Funktionalitätsmenge und goto. Schon gar nicht
in dem Sinne, dass viel Funktionalität ein goto bedingt, was du ja
implizierst.
Mark B. schrieb:> Mit "viele" meinst Du sicher:>...
Ja, unter anderem. Endlich hast du mal ein paar der immer wieder
vorgetragenen Beispiele gefunden. Bravo.
blablablubb schrieb:> Mark B. schrieb:>> 1.) Ursache: zu viel Code/zu viel Funktionalität in einer Funktion>> 2.) Wirkung: Unnötige Verwendung von goto,>> Das ist doch an den Haaren herbeigezogener Mumpitz. Es besteht doch kein> Zusammenhang zwischen der Funktionalitätsmenge und goto.
Der Zusammenhang besteht zum Beispiel über die Verschachtelungstiefe,
aus der mancher Programmierer (ich nicht) gerne mit goto "ausbricht".
Mark B. schrieb:> aus der mancher Programmierer (ich nicht) gerne mit goto "ausbricht".
Ja, das ist doch aber kein Muss.
Nur weil einige das machen, muss man doch goto nicht verteufeln.
Der Ansatz von Yalu ist gut, die endgültige Funktion aber unsicher :-(
Besser so. Das ist wasserdicht, auch wenn man eher selten 64k Ports
benutzen wird. Das ist so ähnlich wie die seltenen, nicht atomaren
Zugriffsfehler auf ISR Variablen . . .
Mark B. schrieb:> ...gibt es nach dem Unit Test noch einen Integrationstest und/oder> entsprechend Regressionstests, die von jemand anderem als dem Entwickler> durchgeführt werden.
Wie viele Tests hättest Du denn gern. Es wird keinen 100% fehlerfreien
Code geben, das müssen wir nun halt mal akzeptieren.
Ohne jetzt hier noch einen Streit über die Qualität von
Programmiersprachen vom Zaune brechen zu wollen behaupte ich jetzt mal,
das die Qualität des Codes und/oder die Fehlerhäufigkeit schon davon
abhängig ist, was der jeweilige Compiler / Interpreter an Schweinereien
im Code zuläßt.
Und da kannst Du Testszenarien ohne Ende machen, wenn ein ein spezieller
Fall nicht bedacht wird, wird es krachen wenn er denn eintritt.
Ich hab jetzt auch so einen Fall wo ein ganz Schlauer meint mit C# und
Unit Test wird alles gut. Denkste! Mit 2 Klicks bringe ich das Programm
zum Absturz und zwar so das es nicht mehr startbar ist und neu
installiert werden muß.
Zeno
blablablubb schrieb:> Falk B. schrieb:>> u16_t i;>>>> for (...; i>0; ...) {>> Ach bitte...
Wie würdest du es schreiben? Ich würde vermutlich sowas machen:
Daniel A. schrieb:> u16_t i;> for( i=0; --i; ) {
Ach du lieeebe Zeit.
Rückwärtszählende Schleifen.
Schleifen, die Überlauf ausnutzen.
Das kommt dabei raus, wenn man krampfhaft versucht goto oder
early-return zu vermeiden.
Warum nicht einfach ganz trivial vorwärts zählen und bei
Abbruchbedingung die Funktion sofort mit early-return verlassen? Das
wäre vermutlich zu einfach.
Hallo,
ich würde dem bereits praktizierten Logikfehler „bei Praktikern schauen”
gern ganz kurz noch ein weiteres Kapitel anfügen.
Gotos getestet mit grep -R "goto \\w\\+;" * | wc -l
und kurzer Sichtkontrolle ohne wc:
apache-httpd 265
git 760
gnu scientific library 69
mysql server 7215
postgreSQL 2542
glibc 2070
mehr großer und etablierter c-Code fiel mir so schnell nicht ein.
Wahnsinn, dieses krasse Stümpertum überall.
vlg
Timm
rhf schrieb:> Herbert P. schrieb:>>> Nicht zuletzt deshalb gilt diese Regel auch in meinen Vorlesungen>> und Übungen, obwohl sie meine Studierenden auch immer wieder gerne>> wegdiskutieren wollen...>> Was habe ich diese auf Formalien herum reitenden Professoren während> meines Studiums gehasst. Meistens waren das auch genau die, bei denen> ich am wenigsten gelernt habe, da sie aus ihrer fachlichen "Ecke" nicht> heraus kamen. Aber egal.
Nun ja, Ansichtssache. Ich sehe das nicht als Formalie. Über die Jahre
habe ich Pascal, Fortran, Prolog, Assembler, PL/I, C und andere
praktisch in der Industrie verwendet. Mit und ohne goto, und ich habe
meine Lektion gelernt. Ich finde aber, das es nicht notwendig ist, dass
meine Studis alle meine Fehler wiederholen müssen. Die meisten verstehen
es, und ein paar wenige brauchen halt etwas Nachdruck.
> Ich hätte aber einen Vorschlag für dich: Wenn du so davon überzeugt bist> das die Verwendung von goto absolut abzulehnen ist, lasse doch von> deinen Studenten einfach mal ein nicht triviales Programm schreiben in> dem ausschließlich goto erlaubt ist. Ich finde mit einen solchen> Beispiel könnte man doch sicherlich sehr anschaulich zeigen was für oder> gegen die Verwendung von goto spricht.>>
Das ist gar keine dumme Idee. Ich danke dir für diese Anregung. Das
werde ich wirklich mal ausprobieren. Bin gespannt, was dabei
herauskommt. :D
Herby
Timm R. schrieb:> apache-httpd 265> git 760> gnu scientific library 69> mysql server 7215> postgreSQL 2542> glibc 2070>> mehr großer und etablierter c-Code fiel mir so schnell nicht ein.> Wahnsinn, dieses krasse Stümpertum überall.
Nochmal für alle, die es immer noch nicht verstanden haben:
Quantität bezeugt keine Qualität.
Falk B. schrieb:> Der Ansatz von Yalu ist gut, die endgültige Funktion aber unsicher :-(
Mir ging es nicht darum, Fehler in dem Code zu korrigieren, sondern zu
zeigen, wie man das Goto eliminieren kann, ohne dabei am Verhalten der
und der Effizienz der Funktion etwas zu ändern.
Natürlich hast du recht, die Funktion läuft in eine Endlosschleife, wenn
alle Ports belegt sind. Der Fehler ist im Original auch längst behoben:
http://git.savannah.gnu.org/cgit/lwip.git/commit/src/core/tcp.c?id=112158b056c7b55498537cdb60e106b8075f465d
Witzigerweise wurde im gleichen Aufwasch auch der Kommentar mit dem
"nastly hack featuring 'goto' statements" entfernt, die Goto-Anweisung
selber wurde aber beibehalten :)
> for (i=0xFFFF; i>0; i--) {> if (port++ >= TCP_LOCAL_PORT_RANGE_END) {> port = TCP_LOCAL_PORT_RANGE_START;> }> if (!port_is_in_use(port)) break;> }
Das stimmt so nicht, denn es werden nicht alle 65535 Ports, sondern nur
diejenigen im Bereich von TCP_LOCAL_PORT_RANGE_START bis einschließlich
TCP_LOCAL_PORT_RANGE_END verwendet.
Yalu X. schrieb:> Witzigerweise wurde im gleichen Aufwasch auch der Kommentar mit dem> "nastly hack featuring 'goto' statements" entfernt, die Goto-Anweisung> selber wurde aber beibehalten :)
Im Grunde genommen ist das nur halt leider nicht witzig, sondern ein
Armutszeugnis.
Ich bin überzeugt davon, dass viele der von Timm Reinisch gelisteten
Vorkommen von goto von einer ähnlich "guten" Qualität sind.
Es zeigt sich leider immer wieder: Auf Codequalität achtet so gut wie
kein Schwein. :-(
Um wirklich nicht mehr in die Goto-Versuchung zu kommen, würde ich mir
ein solches Sprachmittel wünschen (in Pseudocode):
1
Procedure Foo()
2
3
if xy then EXIT
4
5
POSTEXIT
6
Cleanup...
7
End Procedure
D.h. dass man einen Bereich am Ende der Funktion/Routine definieren
kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet
wird. Das hielte ich auch für sauberen Code, da klar ist, wohin
gesprungen wird.
Mark B. schrieb:> Nochmal für alle, die es immer noch nicht verstanden haben:>> Quantität bezeugt keine Qualität.
Du behauptest also ernsthaft, dass folgende Projekte qualitativ
minderwertig sind?
> apache-httpd 265> git 760> gnu scientific library 69> mysql server 7215> postgreSQL 2542> glibc 2070
Ich würde es stark bezweifeln.
Hi,
Zeno schrieb im Beitrag #4547438:
> Mark B. schrieb:>>> Wahnsinn, dieses krasse Stümpertum überall.>>>> Nochmal für alle, die es immer noch nicht verstanden haben:>>>> Quantität bezeugt keine Qualität.>> Dieses Statement war doch klar - alles Stümper.> @Timm: Hast Du etwa was anderes erwartet?
Die Quantität der Fehler und Missverständnisse beim auf-teufel-komm-raus
Ausmerzen des einen Goto belegt eigentlich alles :-)
vlg
Timm
Tommi schrieb:> D.h. dass man einen Bereich am Ende der Funktion/Routine definieren> kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet> wird. Das hielte ich auch für sauberen Code, da klar ist, wohin> gesprungen wird.
Das gibt es doch schon, z.B. bei Objektpascal.
1
try
2
....
3
finally
4
....
5
end;
Man schreibt den kompletten Code für die Funktion zwischen try und
finally und das was man immer machen möchte, also unbedingt ausführen
möchte unabhängig davon ob während der Abarbeitung des Codes zw. try und
finally ein Fehler passiert oder nicht, kommt zw. finally und end. Der
Code zw. finally und end wird immer ausgeführt. Der im Codeteil der
Funktion evtl. gebildete Returnwert wird natürlich an die aufrufende
Funktion zurückgegeben, man kann ihn aber auch noch im finally/end-Block
ändern, was z.B. bei einem Fehler Sinn macht.
Zeno
Tommi schrieb:> D.h. dass man einen Bereich am Ende der Funktion/Routine definieren> kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet> wird.
Viele Sprachen mit Exceptions bieten dies. In Python heißt es "finally"
bzw. der Exception-Handler selbst. Und in Sprachen, die das nicht
bieten, kann mal es halt sehr schön mit goto machen. Da spricht absolut
nichts dagegen.
> Das hielte ich auch für sauberen Code, da klar ist, wohin> gesprungen wird.
Bei goto ist nicht klar wohin gesprungen wird??
Falk B. schrieb:> Schaff ich das noch heute noch?> u16_t i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START;>> for (; i>0; i--) {
Ich gehe mal davon aus, dass END und START der jeweils letzte und erste
gültige Port sind.
Dann zählt es eins zu wenig.
Also.
> Schaff ich das noch heute noch?
Viel Glück :)
Zeno schrieb:> und das was man immer machen möchte, also unbedingt ausführen> möchte unabhängig davon ob während der Abarbeitung des Codes zw. try und> finally ein Fehler passiert oder nicht, kommt zw. finally und end. Der> Code zw. finally und end wird immer ausgeführt.
Das ist allerdings kein Ersatz für einen per goto gebauten
fall-through-error-handler. (siehe Linux Kernel für Beispiele).
Zeno schrieb:> Das gibt es doch schon, z.B. bei Objektpascal.> [...]try [...] finally [...] end;
Geht halt nur für Exceptions. Im normalen Ablauf hat man ja nicht so
viele davon. Und mit Exceptions wild um sich zu werfen ist auch nicht
die Lösung.
blablablubb schrieb:> Bei goto ist nicht klar wohin gesprungen wird??
Nicht wenn man das Sprungziel nicht kennt. Es ann ja irgendwo stehen.
Von daher halte ich die Verwendung von Goto für in Ordnung, wenn man
immer nach vorne springt und idealerweise ans Ende der Funktion. Wenn
man sich an diese Konvention hält, weiß man wo sich das Sprungziel
befindet ohne direkt zu schauen. Das ist ja gerade der Vorteil von EXIT
und BREAK.
blablablubb schrieb:> Das ist allerdings kein Ersatz für einen per goto gebauten> fall-through-error-handler. (siehe Linux Kernel für Beispiele).
An dieser Stelle (Linuxkernel) kann ich nicht wirklich mit reden
Aber bei meinem Beispiel kann man, sofern Fehler passieren schon genau
festlegen was gemacht werden soll, da ja der finally Zweig im Fehlerfall
sofort angesprungen wird. Man wertet dann einfach die Exceptionvariable
aus und fertig.
Man kann ja zuerst die Exceptionvariable auslesen und entsprechend
behandeln und danach seinen Aufräumcode abarbeiten.
Was spricht dagegen das die Funktion einen Record zurückgibt, der das
Exceptionobject und den Rückgabewert der Funktion enthält? Man hat dann
alle Möglichkeiten der Fehlerbehandlung.
Zeno
Tommi schrieb:> Es ann ja irgendwo stehen.
Nein kann es nicht. Es muss innerhalb in der Funktion stehen. Und wenn
man es dort nicht findet, sollte man wegen Unfähigkeit aufhören zu
programmieren.
> Von daher halte ich die Verwendung von Goto für in Ordnung, wenn man> immer nach vorne springt und idealerweise ans Ende der Funktion.
So sehe ich das auch.
Zeno schrieb:> da ja der finally Zweig im Fehlerfall> sofort angesprungen wird.
Und es wird auch im Nicht-fehler-fall angesprungen. Und das kann ein
Problem sein.
Einen exklusiven Fehlerpfad kann man nur mit vielen Unterfunktionen oder
einer komplexen Unterfunktion machen, wenn man goto nicht verwendet. Und
selbst dann ist er unschön im Vergleich mit einer
goto-fallthrough-Lösung.
Zeno schrieb:> Was spricht dagegen das die Funktion einen Record zurückgibt, der das> Exceptionobject und den Rückgabewert der Funktion enthält? Man hat dann> alle Möglichkeiten der Fehlerbehandlung.
Dagegen spricht, dass das nicht der Fall ist, den
fall-through-error-handler behandelt. Er behandelt die Fehler
innerhalb der Funktion.
Tommi schrieb:> Geht halt nur für Exceptions. Im normalen Ablauf hat man ja nicht so> viele davon. Und mit Exceptions wild um sich zu werfen ist auch nicht> die Lösung.
Also bei Objectpascal gibt jede Menge Exceptions. Es gibt aber ein paar
Sachen wo selbige nicht generiert werden, z.B. bei den klassischen
Dateigeschichten wie reset, close, blockread etc.. Da kann man aber
Fehler über IOResult abfangen und sobald selbiges ungleich 0 ist eine
Exception generieren und schon landet man im finally-Block. Das heißt ja
jetzt nicht das man damit wild mit Exception um sich wirft.
Man kann IOResult aber auch in einer Variable speichern, die man dann im
finally-Block abfragt.
Noch einmal der finally-Block wird immer! durchlaufen unabhängig davon
ob eine Exeption aufgetreten ist oder nicht.
Zeno
blablablubb schrieb:> Dagegen spricht, dass das nicht der Fall ist, den> fall-through-error-handler behandelt. Er behandelt die Fehler> innerhalb der Funktion.
Okey! Ich kann die Fehlerbehandlung auch innerhalb der Funktion im
finally-Block durchführen. Es ist auch kein Problem wenn während der
Fehlerbehandlung eine andere Funktion erforderlich wäre, der
finally-Block wird in jedem Fall vollständig durchlaufen, es sei denn
ich produziere auch dort Fehler, dann knallt es halt. Allerdings kann
ich auch im finally-Block kritischen Code mit try/finally oder
try/except kapseln, d.h. ich Exceptionblöcke schachteln.
Zeno
blablablubb schrieb:> Und es wird auch im Nicht-fehler-fall angesprungen. Und das kann ein> Problem sein.
Es ging ja darum eine Funktion zu haben, die immer aufräumt bevor sie
verlassen wird. War dieser Post auf den ich da geantwortet habe.
Tommi schrieb:> Um wirklich nicht mehr in die Goto-Versuchung zu kommen, würde ich mir> ein solches Sprachmittel wünschen (in Pseudocode):> Procedure Foo()>> if xy then EXIT>> POSTEXIT> Cleanup...> End Procedure>> D.h. dass man einen Bereich am Ende der Funktion/Routine definieren> kann, welcher bei einem Exit aus der Funktion raus noch abgearbeitet> wird. Das hielte ich auch für sauberen Code, da klar ist, wohin> gesprungen wird.
Naja es ist halt wie immer, man muß schon wissen was man tut. Ich
benutze das Konstrukt gerne wenn ich Ressourcen, Zeiger etc. in jedem
Fall freigeben möchte.
Zeno
Daniel A. schrieb:> Ich denke es geht um soein Konstrukt?
Könnte man problemlos im try/finally-Konstrukt umsetzen - vielleicht
nicht ganz so elegant wie Du das in Deinem Beispiel gemacht hast.
Oder man macht es genauso mit goto - geht in Pascal auch.
Zeno
Daniel A. schrieb:> Ich denke es geht um soein Konstrukt?
Fast.
Ein ähnliches Konstrukt, das im Nicht-Fehlerfall keine Aufräumarbeiten
macht, geht mit finally nur mit zusätzlichen Krücken.
blablablubb schrieb:> Ein ähnliches Konstrukt, das im Nicht-Fehlerfall keine Aufräumarbeiten> macht, geht mit finally nur mit zusätzlichen Krücken.
Na dann bin ich mal froh, das mein Konstrukt im (nicht) Fehlerfall alle
Aufräumarbeiten macht ;)
blablablubb schrieb:> Du hast es nicht verstanden.
Ach so, es ging darum dass die Klammern bei try - finally verhindern,
dass man ein Cleanup auslassen kann...
blablablubb schrieb:> Ein ähnliches Konstrukt, das im Nicht-Fehlerfall keine Aufräumarbeiten> macht, geht mit finally nur mit zusätzlichen Krücken.
Eigentlich nicht.
1
try
2
try
3
....//beliebiger Code
4
except
5
....//aufräumen (nur im Fehlerfall)
6
end;
7
finally
8
....//alles was man sonst so noch machen will(auch bei Fehler)
Zeno schrieb:> Eigentlich nicht.
ja bla.
Man kann das natürlich hinfrickeln, dass es geht. z.B. wie in deinem
Beispiel mit einem verschachtelten try-Block. Oder mit einer
zusätzlichen Variablen.
So elegant wie mit goto geht es allerdings nicht.
blablablubb schrieb:> So elegant wie mit goto geht es allerdings nicht.
Das habe ich ja auch nicht behauptet. Habe eigentlich von Anfang an in
Frage gestellt ob ich Daniels Beispiel mit try so elegant hinbekomme.
Habe im Übrigen kein Problem damit, das er es mit goto's gelöst hat. Ich
finde ein schönes Beispiel wie man goto einsetzen kann.
Aber warte mal ab bis die Götter des Nicht-goto's wieder erwacht sind.
blablablubb schrieb:> Mark B. schrieb:>> Nochmal für alle, die es immer noch nicht verstanden haben:>>>> Quantität bezeugt keine Qualität.>> Du behauptest also ernsthaft, dass folgende Projekte qualitativ> minderwertig sind?
Ich sage nichts anderes, als dass auch schlechter Code funktionieren
kann. Beweise dafür gibt es hunderttausendfach. Einfach mal die Augen
öffnen.
Zeno schrieb im Beitrag #4547438:
> Mark B. schrieb:>>> Wahnsinn, dieses krasse Stümpertum überall.>>>> Nochmal für alle, die es immer noch nicht verstanden haben:>>>> Quantität bezeugt keine Qualität.>> Dieses Statement war doch klar - alles Stümper.> @Timm: Hast Du etwa was anderes erwartet?
Trolle zeichnen sich unter anderem dadurch aus, dass sie anderen Leuten
Worte in den Mund legen. Es wäre nett, wenn Du woanders weitertrollen
könntest.
Mark B. schrieb:> Ich sage nichts anderes, als dass auch schlechter Code funktionieren> kann.
Warum soll denn eine Lösung mit goto schlechterer Code sein?
Mark B. schrieb:>> Du behauptest also ernsthaft, dass folgende Projekte qualitativ>> minderwertig sind?>> Ich sage nichts anderes, als dass auch schlechter Code funktionieren> kann.
Und damit implizierst du, dass die genannten Beispiele qualitativ
schlechten Code haben. Und das ist geradezu lächerlich.
Wenn du das nicht implizieren würdest, wäre dein Argument unbrauchbar
für diese Diskussion, in der es um goto geht.
Mark B. schrieb:> Trolle zeichnen sich unter anderem dadurch aus, dass sie anderen Leuten> Worte in den Mund legen. Es wäre nett, wenn Du woanders weitertrollen> könntest.
Ich lasse mir von Dir nicht den Mund verbieten.
Du bist derjenige der allen anderen stümperhaftes Programmieren
unterstellt, selbst Leuten die Software geschrieben haben, die seit
Jahren millionenfach erfolgreich im Einsatz ist und das sogar im
Serverbetrieb. Dafür das das Programmieren mit goto so stümperhaft ist
läuft diese Software außerordentlich stabil und zuverlässig, wie z.B.
der Apache Webserver, um nur ein Beispiel zu nennen. Die Leute die das
Teil programmiert haben können also nicht so viel falsch gemacht haben.
Ich glaube Du leidest an einer gehörigen Portion Selbstüberschätzung und
deshalb mußt Du Dich nicht wundern, wenn entsprechende Kommentare
kommen.
Du hälst stur an Deinen Dogmen fest und bist Dir offenbar zu fein mal
über den Tellerrand zu schauen. Aber warum solltest Du das auch tun,
denn die anderen sind ja eh alles Deppen. Fehlt nur noch das wir Dir
huldigen müssen.
Wir kennen mittlerweile Deine Meinung, wissen auch das Du auf selbiger
beharrst und in diesem Sinne solltest eher Du dich trollen, da Du diesen
Thread nicht weiter bereicherst.
Zeno
Mitlesender schrieb:> Dafür das das Programmieren mit goto so stümperhaft ist> läuft diese Software außerordentlich stabil und zuverlässig,
Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg
keine Rolle.
Plakatives Beispiel: Wieviele Deutsche sind der Meinung, Spinat enthalte
besonders viel Eisen? Wie oft hat man schon gehört, Eskimos hätten
deutlich mehr Wörter für Schnee als Europäer?
Diese Meinungen werden Millionenfach vertreten, machen sie aber dennoch
nicht richtig. Sie sind in der Tat falsch.
Anderes Beispiel. 2+3 = 5. Daraus kannst Du aber nicht schließen, dass
jede 5 dieser Welt die Summe aus 2+3 ist. Eine 5 kann auch die Summe aus
1+4 sein.
Was Du machst, ist ein ganz banaler Argumentationsfehler. Aus "B folgt
aus A" kann man eben gerade nicht schließen, "A folgt aus B".
Programmierer schrieb:> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg> keine Rolle.
Doch das tut es.
Wenn eine Art eine Software zu entwickeln in Millionen von Codezeilen
äußerst erfolgreich eingesetzt wird, dann ist diese Art nicht schlecht
oder gar stümperhaft.
Die Software ist qualitativ hochwertig und funktional korrekt.
Der Vergleich mit irgendwelchen Volksweisheiten ist deshalb nicht
zutreffend, weil diese genannten Volksweisheiten eben nachweislich
falsch sind. (= nicht funktional korrekt)
Mark B. schrieb:> blablablubb schrieb:>> Aber es gibt viele legitime Einsatzgebiete für goto. Diese wurden alle>> schon genannt und sind trivial auffindbar.>> Mit "viele" meinst Du sicher:> -Kernel Hacking unter Linux> -Kernel Hacking unter OpenBSD> -Kernel Hacking unter FreeBSD> -Kernel Hacking unter NetBSD> -Kernel Hacking unter blablablubb OS
Nein, in erster Linie "Fehlerbehandlung unter Randbedingungen". In
zweiter Linie "Performancekriterium trumpft elegant-sauberen Code" (z.B.
Jump-Tables). In dritter Linie dann switch/case und early return, die ja
auch nix anderes sind. Beispiele gab es genug.
Es ist bewiesen, dass man immer ohne goto auskommen kann (und sei es
auf Kosten zusätzlicher Variablen, höherer Verschachtelungstiefe,
zusätzlichen Funktionsaufrufen etc.) und daher wirst du immer
argumentieren, dass man das goto dann auch wegmachen kann und der Code
zwingend besser wird.
Und das, lieber Mark, ist Religion.
Wir sind uns hier alle einig, dass man ohne goto auskommen kann.
Wir sind uns aber nicht einig, dass man für guten Code ohne goto
auskommen muss.
S. R. schrieb:> Wir sind uns hier alle einig, dass man ohne goto auskommen kann.> Wir sind uns aber nicht einig, dass man für guten Code ohne goto> auskommen muss.
Schön geschrieben!
Programmierer schrieb:> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg> keine Rolle.
Richtig, das Spielt keine Rolle. Und eine Sache wird auch nicht richtig
nur weil genügend dran glauben oder sagen es sei richtig. Die
Contra-goto-Fraktion macht hier aber etwas ähnliches indem sie sagt,
dass das Verwenden von goto generell schlechter Stil sei. Zumindest ich
lese das hier zwischen den Zeilen der Contra-goto-Fraktion heraus. Man
kann viel Mist mit goto machen, man kann es aber auch so intelligent
benutzen wie andere Dinge von C.
Programmierer schrieb:> Mitlesender schrieb:>> Dafür das das Programmieren mit goto so stümperhaft ist>> läuft diese Software außerordentlich stabil und zuverlässig,>> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg> keine Rolle.
Exakt so ist es. Endlich mal einer, der es verstanden hat.
> Was Du machst, ist ein ganz banaler Argumentationsfehler. Aus "B folgt> aus A" kann man eben gerade nicht schließen, "A folgt aus B".
Eben eine klassische "logical fallacy".
blablablubb schrieb:> Doch das tut es.> Wenn eine Art eine Software zu entwickeln in Millionen von Codezeilen> äußerst erfolgreich eingesetzt wird, dann ist diese Art nicht schlecht> oder gar stümperhaft.
Dieses Argument ist völlig an den Haaren herbei gezogen. Unter anderem
mal goto zu verwenden ist keine "Art zu programmieren."
> Die Software ist qualitativ hochwertig und funktional korrekt.
Möchtest Du bitte den Unterschied zwischen Binary und Sourcecode
verstehen?
Eine Software kann funktionieren, und sogar gut funktionieren - das
heißt aber noch lange nicht, dass auch der Sourcecode dazu von einer
hohen Qualität ist. Das sind einfach zwei verschiedene Dinge.
Die Schlussfolgerung "Weil Linux gut ist, dann muss auch die Art und
Weise wie der Linux Kernel programmiert ist gut sein" ist schlichtweg
unzutreffend. Das eine folgt einfach nicht aus dem anderen.
Falls Du schon mal davon gehört hast: Es gibt so genannte "Big Balls of
Mud". Das sind Software-Systeme, die von außen betrachtet mehr oder
weniger gut funktionieren, die aber im Inneren eine sehr bescheidene
Qualität aufweisen.
https://en.wikipedia.org/wiki/Big_ball_of_mud
Mark B. schrieb:> Die Schlussfolgerung "Weil Linux gut ist, dann muss auch die Art und> Weise wie der Linux Kernel programmiert ist gut sein" ist schlichtweg> unzutreffend.
Achso. Man kann also mit schlechtem Quelltext ein gutes Binary erzeugen.
Warum also dann die Diskussion um goto und Programmierstile, wenn es
doch egal ist, weil das Ergebnis ja ohnehin gut ist?
>Unter anderem>mal goto zu verwenden ist keine "Art zu programmieren."
sondern?
blablablubb schrieb:> Mark B. schrieb:>> Die Schlussfolgerung "Weil Linux gut ist, dann muss auch die Art und>> Weise wie der Linux Kernel programmiert ist gut sein" ist schlichtweg>> unzutreffend.>> Achso. Man kann also mit schlechtem Quelltext ein gutes Binary erzeugen.> Warum also dann die Diskussion um goto und Programmierstile, wenn es> doch egal ist, weil das Ergebnis ja ohnehin gut ist?
Jemand, der Ahnung von SW-Entwicklung hat, würde eine solche Frage nicht
stellen. Selbst der Dümmste versteht, dass es besser ist eine Codebasis
zu haben, die gut strukturiert, gut lesbar und gut zu warten ist.
Mit solchen Dummköpfen mag ich nicht länger diskutieren. Ich bin raus.
Mark B. schrieb:> Selbst der Dümmste versteht, dass es besser ist eine Codebasis> zu haben, die gut strukturiert, gut lesbar und gut zu warten ist.
Genau. Und deshalb setze ich goto ein, weil es den Quellcode lesbarer
und besser wartbar macht.
> Mit solchen Dummköpfen mag ich nicht länger diskutieren.
Lieber nicht mit Argumenten kommen, gell?
Huch, da schaut man mal wieder rein - und ihr diskutiert immer noch.
S. R. schrieb:> Wir sind uns hier alle einig, dass man ohne goto auskommen kann.> Wir sind uns aber nicht einig, dass man für guten Code ohne goto> auskommen muss.
Ja, ja und nochmals JA. Sowas hätte definitiv als ultimatives Schlußwort
gelten können für diesen Thread. Aber religiös angehauchte Eiferer wie
Mark bemerken nicht, wenn sie sich verstiegen haben.
Mitlesender schrieb:> Ich glaube Du leidest an einer gehörigen Portion Selbstüberschätzung und> deshalb mußt Du Dich nicht wundern, wenn entsprechende Kommentare> kommen.
Nun ja, du Mitlesender, ich meine da eine Feinkorrektur anbringen zu
müssen: Mark leidet nicht an seiner objektiv vorhandenen
Selbstüberschätzung. Vielmehr leidet er darunter, daß sie beim Rest der
Welt nicht so recht ankommen will und ihm das auch mehr oder weniger
dezent gesagt wurde.
Aber anstatt mal in sich zu gehen und sich zu fragen, WARUM sowas wie
"goto" in allen Progremmiersprachen (nun ja, jedenfalls in den nicht
rein Deklarativen) vorkommt, betitelt er den Rest der Welt als
Dummköpfe. Sind also alle Erfinder aller existierenden
Programmiersprachen stupide Dummköpfe???
So.
Eigentlich sollte man sich mal wieder an den gesunden Menschenverstand
erinnern. Goto gehört zum Sprachumfang und es sollte dem verständigen
Programmierer im jeweiligen Einzelfall überlassen bleiben, ob und wo er
es benutzt. Alle Pauschal-Verurteilungen sind Oberbockmist - und das
sollte es hier gewesen sein.
W.S.
W.S. schrieb:> Aber anstatt mal in sich zu gehen und sich zu fragen, WARUM sowas wie> "goto" in allen Progremmiersprachen (nun ja, jedenfalls in den nicht> rein Deklarativen) vorkommt,
Ersetze "allen" durch "vielen", denn es gibt durchaus imperative
Programmiersprachen ohne Goto, z.B. Java, Javascript, Python, Bash,
Rust, Groovy und Swift.
Mark B. schrieb:> Dieses Argument ist völlig an den Haaren herbei gezogen. Unter anderem> mal goto zu verwenden ist keine "Art zu programmieren."
Du kannst keine andere Meinung akzeptieren. Mehr kann man einfach nicht
dazu sagen. Jegliche weitere Diskussion ist deshalb zwecklos.
Zeno
Mark B. schrieb:> Mit solchen Dummköpfen mag ich nicht länger diskutieren. Ich bin raus.
Wenn es keine Argumente mehr hat dann Kopf in den Sand und beleidigt
sein. Aber in diesem Fall ist das gut so.
Wie man sich derart verbissen um den sinnlosen Returnwert von main() in
Programmen für betriebssystemfreie embedded-Umgebungen streiten kann ...
;-). Üblicherweise ist es doch so, dass der Compiler auch schon vor C99
nicht auf einem return besteht, weil er weiss, dass hinter der
Hauptschleife nix los ist.
Es gibt übrigens einen banalen Grund, weshalb man in Sprachen wie C das
"goto" nicht gänzlich streichen sollte: C Programme werden nicht nur von
Menschen geschrieben. In maschinell produziertem C Code kann goto
sinnvoll bis notwendig sein.
A. K. schrieb:> ... um den sinnlosen Returnwert ...
Der Returnwert war nur "Nebenprodukt". Eigentlich ging es um die
Verwendung von goto.
Ich meine W.S. hatte geschrieben, das er mit goto die Compilermecker
unterdrücken kann bei gleichzeitigem Verzicht auf return 0. Mehr
eigentlich nicht. Aber genau das hat die Hüter des "nicht goto" erst mal
so richtig auf den Plan gerufen. Verstehen kann ich das auch nicht.
Bisher habe ich auch immer while(1) für die Endlosschleife benutzt. Das
for(;;) kannte ich bisher nicht. Insofern hat der Thread ja doch was
gebracht und ich habe was dazu gelernt. Ebenso kannte ich W.S.'s goto
Lösung nicht u.a. auch aus dem Grund goto nur zu verwenden wenn es
wirklich sinnvoll ist. Und wenn ich ganz ehrlich bin, gefällt mir diese
goto Lösung immer besser, auch wenn sie rückwärts springt. Aber sie
erzeugt in dem Fall durchaus verständlichen Code , der nicht weniger
schlecht als while(1) ist und seinen Zweck erfüllt.
Das ist jedenfalls meine (abschließende) Meinung dazu. Es steht
natürlich jedem frei das anders zu sehen und zu handhaben. Da ich das µC
Geschäft lediglich privat betreibe muß ich mich keinen Dogmen
unterwerfen und bin froh darüber.
Zeno
Zeno schrieb:> Mark B. schrieb:>> Mit solchen Dummköpfen mag ich nicht länger diskutieren. Ich bin raus.>> Wenn es keine Argumente mehr hat dann Kopf in den Sand und beleidigt> sein. Aber in diesem Fall ist das gut so.
Ich habe wiederholt nach Beispielen gefragt, die die Aussage "GOTO kann
richtig gut sein" untermauern. Niemand war dazu in der Lage, ein solches
konkretes Beispiel zu liefern.
Ich bleibe dabei: Die meisten Verwender von goto verwenden es deshalb,
weil sie nicht verstanden haben wie man Code geschickt auf möglichst
kleine Funktionen aufteilt. Sie machen zu große Funktionen und springen
dann innerhalb einer solchen fröhlich hin und her, anstatt die
eigentliche Ursache für das "Springen-müssen" abzustellen.
Und ja, ich akzepziere es wenn mir jemand das Gegenteil beweist. Dann
aber bitte nicht einfach nur behaupten, sondern auch tatsächlich
liefern. Ein Verweis auf 384.576 Verwendungen von goto beweist gar
nichts. Ich kann Dir zehn Milliarden Zeilen schlechten Code zeigen,
schlechten Code mit goto, schlechten Code ohne goto, schlechten Code von
Anfängern, schlechten Code von Leuten die seit Jahren programmieren. Was
beweist das? Genau: Nichts.
Zeig mir:
-GUTEN Code mit goto,
-der durch Refactoring nicht mehr besser wird,
-der anerkannte Regeln des Software-Designs befolgt, so wie man sie in
guter Literatur zu dem Thema findet.
Dann bin ich überzeugt.
Und nun gehe hin, und kaufe Dir zum ersten Mal in Deinem Leben ein Buch
über Software-Design. Arbeite es durch, und Du wirst danach ein besserer
Entwickler sein. Versprochen.
Mark B. schrieb:> -der anerkannte Regeln des Software-Designs befolgt, so wie man sie in> guter Literatur zu dem Thema findet.
Da die anerkannten Regeln gemeinhin goto verbieten... ;-)
Ich finds praktisch. Und ich benutze es auch ab und zu, insbesonders um
vorzeitig aus Funktionen mit Fehlercode auszusteigen (die Alternative
wären entweder mehrere verteilte returns (das hasse ich wirklich) oder
aufwändigere Konstrukte, die gar keinen Sinn machen, sondern nur dazu
dienen, dass einfache goto zu vermeiden.
Ja, es geht ohne. Besser, übersichtlicher oder sicherer wird es deshalb
nicht automatisch.
Hallo A.K.
A. K. schrieb:> Mark B. schrieb:>> -der anerkannte Regeln des Software-Designs befolgt, so wie man sie in>> guter Literatur zu dem Thema findet.>> Da die anerkannten Regeln gemeinhin goto verbieten... ;-)
du hast eine Smiley dran, trotzdem noch mal zur Klarstellung:
Tun sie nicht. Der einzige Beleg dazu, der von den Verpönern bisher
geliefert wurde war MISCRA-C:2012 und ein heftiger Schuss in den Ofen.
Denn gerade in MISRA-C ist das Goto Verbot von "mandatory" auf
"advisory" abgestuft worden und es sind sogar neu Hinweise eingeführt
worden, wie ein gutes Goto auszusehen hat.
vlg
Timm
Programmierer schrieb:> Nochmals. Wer etwas sagt, oder wieviele etwas sagen, spielt schlichtweg> keine Rolle.
vielleicht solltest Du aber lieber beim Programmieren bleiben und dich
nicht auf ungewohntes Terrain begeben?
> Plakatives Beispiel: Wieviele Deutsche sind der Meinung, Spinat enthalte> besonders viel Eisen? Wie oft hat man schon gehört, Eskimos hätten> deutlich mehr Wörter für Schnee als Europäer?
Die Autoren der genannten Software haben sich nicht nur an die
Projekt-Guidelines gehalten, sondern sind auch keine Lieschen Müller.
Wenn schon, dann müsste Dein Vergleich lauten: Wieviele Chemiker,
Biologen und Ökotrophologen sind der Meinung, Spinat enthalte besonders
viel Eisen und können diese Meinung unwidersprochen von ausgewiesenen
Experten über Jahrzehnte deklamieren.
Das sieht dann schon anders aus. Was Du da gemacht hast, war nicht
plakativ, sondern angewandter Rabulismus.
Aber Du gehörst sicher zu den Leuten, die stehen bleiben, wenn 6 Leute
vom Kampfmittelräumdienst aus der Absperrung nebenan gesprintet kommen.
> Anderes Beispiel. 2+3 = 5. Daraus kannst Du aber nicht schließen, dass> jede 5 dieser Welt die Summe aus 2+3 ist. Eine 5 kann auch die Summe aus> 1+4 sein.>> Was Du machst, ist ein ganz banaler Argumentationsfehler. Aus "B folgt> aus A" kann man eben gerade nicht schließen, "A folgt aus B".
Ei, das haben wir uns aber schön an den Haaren herbeigezogen. Was
bitteschön hat ein falscher Modus tollens mit dem Gewicht von
Autoritätsargumenten zu tun? Nicht jeder Unsinn ist mit allem verwandt,
was Du für Unsinn hältst.
Autoritätsargumente sind nicht trivial wahr, sondern Gegenstand von
Abwägungen, sie sind aber weder defekt noch per se falsch.
Aber: Drehen wir den Spieß doch um? Möge doch bitte einer der Verpöner
ein großes Open Source Projekt, geschrieben in C, nennen, das kein Goto
enthält?
Oder zumindest endlich mal eine etablierte und verbreitete Richtlinie,
die Goto untersagt.
Vlg
Timm
Timm R. schrieb:> Aber: Drehen wir den Spieß doch um? Möge doch bitte einer der Verpöner> ein großes Open Source Projekt, geschrieben in C, nennen, das kein Goto> enthält?
Hm. Ein großes Projekt, geschrieben in C, mit gutem Software-Design, wo
man bei einem Code Review nicht ständig "What the fuck?" rufen würde.
Hat es so etwas jemals gegeben?
http://www.osnews.com/story/19266/WTFs_m
Mark B. schrieb:> Und nun gehe hin, und kaufe Dir zum ersten Mal in Deinem Leben ein Buch> über Software-Design. Arbeite es durch, und Du wirst danach ein besserer> Entwickler sein. Versprochen.
Du kannst es nicht lassen. Lebe weiter in Deiner Welt mit Deinem
Fanatismus.
Gute Softwareentwickler kennen keine Dogmen, sondern lösen das Problem
und wählen hierfür das Werkzeug/Programmiersprache mit dem/der sich die
Aufgabe am besten lösen läßt. Ein guter Softwareentwickler wird auch den
Sprachumfang einer Programmiersprache ausnutzen und die Sprachelemente
wählen mit denen das Problem am effizientesten gelöst werden. Er kennt
halt keine Dogmen und wird z.B. auch ein goto einsetzen wenn dies Sinn
macht und zu effizienten und gut lesbaren Code beiträgt. Er wird
hingegen ein goto nicht einsetzen, wenn es eine andere gleichwertige
oder bessere Lösung gibt.
Letztendlich ist entscheidend, daß mit der Software das Problem gelöst
wird und diese zuverlässig und stabil funktioniert. Mir als Anwender ist
es völlig wurscht wie die Software die gewünschte Funktionalität
erreicht und ob der Programmierer hierzu goto eingesetzt. Wenn die
Funktionalität vorhanden ist und SW stabil läuft, dann hat sie für mich
eine hohe Qualität.
Mark B. schrieb:> Hm. Ein großes Projekt, geschrieben in C, mit gutem Software-Design, wo> man bei einem Code Review nicht ständig "What the fuck?" rufen würde.> Hat es so etwas jemals gegeben?
Wahrscheinlich nur, wenn diese Software von Herrn Mark Brandis
geschrieben wurde.
Gerade in Deinem letzten Post hast Du wieder einmal bewiesen wie
arrogant Du bist. Alle anderen scheinen ja nach Deinem Verständnis nur
Deppen und Volltrottel zu sein.
Da gibt es nur ein Fazit : Hochmut kommt vor dem Fall.
Zeno
PS: Die Frage ist wie viele große Projekte mit qualitativ hervorragenden
Code hast Du denn schon auf die Beine gestellt? Behaupten kann jeder
viel.
Unabhängig vom ästhetischen Befinden ob "goto's" gut oder schlecht sind,
gibt es vielleicht ein Argument gegen "goto":
Die MISRA-Regeln verbieten es.
( Ich kann leider nur auf die Wikipedia verweisen
- goto soll nicht verwendet werden[6]
MISRA 1998, Regel 56 und MISRA 2004, Regel 10.4
)
Falls man also einmal den Wunsch haben sollte, in der
Automotive-Industrie zu arbeiten, muss man wohl auf das "goto"
verzichten.
chris_ schrieb:> Die MISRA-Regeln verbieten es.
Nicht ganz. Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die
Verwendung aber nicht. Rule 15 behandelt die Verwendung von goto ;)
>Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die>Verwendung aber nicht
Gibt es eigentlich irgendwo im Netz ein Dokument, wo man die MISRA
Regeln einsehen kann?
chris_ schrieb:>>Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die>>Verwendung aber nicht>> Gibt es eigentlich irgendwo im Netz ein Dokument, wo man die MISRA> Regeln einsehen kann?
Google ist dein Freund:
http://archive.redlizards.com/docs/misrac2012-datasheet.pdf
Das wäre aber jetzt auch nicht so schwer gewesen selbst zu finden.
Zeno schrieb:> Gute Softwareentwickler kennen keine Dogmen
Selbstverständlich gibt es Regeln, die man als Programmierer zu
akzeptieren hat. Exakt das unterscheidet einen guten Entwickler von
einem schlechten: Der Gute ist in der Lage, sich an sinnvolle(!) Regeln
zu halten. Er weiß, dass das Ergebnis seiner Arbeit dadurch besser wird.
Der Schlechte programmiert frei Schnauze wie immer er Bock hat, und
produziert dadurch Bockmist. Been there, done that.
Wenn Du eine bestimmte Qualität erreichen willst, ganz besonders wenn
ein Team am Projekt arbeitet und nicht ein Einzelner, dann musst Du
zwingend Regeln aufstellen. Sonst hast Du Wildwuchs. Jeder Programmierer
im Projekt macht dann was er will, und entsprechend beschissen ist
hinterher die Qualität und die Wartbarkeit des Codes.
> Mark B. schrieb:>> Hm. Ein großes Projekt, geschrieben in C, mit gutem Software-Design, wo>> man bei einem Code Review nicht ständig "What the fuck?" rufen würde.>> Hat es so etwas jemals gegeben?> Gerade in Deinem letzten Post hast Du wieder einmal bewiesen wie> arrogant Du bist. Alle anderen scheinen ja nach Deinem Verständnis nur> Deppen und Volltrottel zu sein.
Wer behauptet, dass C gut geeignet für große und komplexe SW-Projekte
sei, der dokumentiert damit dass er nicht viel Ahnung von Software hat.
Die Sprache C war schlicht und ergreifend nie für große, hochkomplexe
SW-Projekte entworfen worden, wie wir sie heute haben. Solche Projekte
mit vielen Millionen Lines Of Code gab es damals, Ende der 60er Anfang
der 70er Jahre, schlicht und ergreifend noch gar nicht.
Entsprechend schlecht ist C für solche Projekte ausgestattet. Das fängt
bei den läppischen Mechanismen für die Fehlerbehandlung an, und hört bei
der sehr zu wünschen übrig lassenden C-Standardbibliothek nicht auf.
Schau Dir Sprachen wie Java, Python und Scala an. Was man da mit wenigen
Zeilen fehlerfrei hinschreiben kann, dafür braucht man in C schon einen
kleinen Urwald an Code. Viel mehr Code nötig, um im Endeffekt das
Gleiche zu tun --> Größeres Fehlerpotenzial.
Niemand hält es heute noch für eine gute Idee, ein großes und komplexes
SW-Projekt in einer Sprache durchzuführen, die den Entwickler so
herzlich wenig dabei unterstützt wie C es eben tut. Außer Dir
vielleicht(?).
C hat seine Berechtigung, wenn man hardwarenah entwickeln will und/oder
eine sehr hohe Ausführungsgeschwindigkeit braucht. Aber selbst dann ist
C++ oftmals die bessere Wahl. Leider kennen viele Programmierer nur ein
Werkzeug, und "if you only have a hammer, then every problem looks like
a nail".
> PS: Die Frage ist wie viele große Projekte mit qualitativ hervorragenden> Code hast Du denn schon auf die Beine gestellt? Behaupten kann jeder> viel.
Ich schreibe seit Jahren Code, der sicherheitstechnisch zertifiziert
wird, vom TÜV und anderen Firmen einem Audit unterzogen wird und vom
Eisenbahnbundesamt abgenommen werden muss. Ansonsten darf das
Schienenfahrzeug mit dem entsprechenden Software-Stand eben nicht fahren
und der Kunde springt uns ins Gesicht. Noch Fragen?
>Die Sprache C war schlicht und ergreifend nie für große, hochkomplexe>SW-Projekte entworfen worden,
hinsichtl. goto ist das Totaler Blödsinn!
Das betr. goto sind prinzipielle Dinge, die rein gar nichts mit einer
speziellen Programmiersprache zu tun haben. Das hast du nicht kapiert.
Und den o.g. Ausschluss kannst du auch nicht machen (und für dieses
Beispiel auch nichts besseres bringen ohne goto).
Offensichtlich redest du nur nach, was man dir vorgibt, wie auch
>Selbstverständlich gibt es Regeln, die man als Programmierer zu>akzeptieren hat.
zeigt.
-------------------------------------
Und nochmal ganz allgemein:
Das Problem besteht (u.a), sobald von MEHREREN Stellen aus die Gleiche
Behandlung (oder gleiche Codeteile) ausgeführt werden sollen.
Bitte kann man jemand diesen Titel im ersten Beitrag ändern damit der
eklatante Rechtschreibfehler behoben wird.
Wenn der Thread nur 1 Tag aktiv wäre hätte man das überleben können,
aber so wird man in der Forumsübersicht jeden Tag mit der Augenkrebs und
Übelkeit verursachenden defekten Rechtscheibung des "verpönnt"
konfrontiert, mir rollen sich da die Fussnägel auf und stülpt sich der
Magen um.
MCUA schrieb:> Das betr. goto sind prinzipielle Dinge, die rein gar nichts mit einer> speziellen Programmiersprache zu tun haben. Das hast du nicht kapiert.
Das stimmt so nicht ganz. In C++ zum Beispiel habe ich ganz andere
Mechanismen zur Fehlerbehandlung, eben die Exceptions. Wenn man ein
solches Sprachmittel verwenden kann, gibt es nun wirklich keinen Grund
mehr stattdessen goto vorzuziehen.
Java kennt kein goto.
Python kennt kein goto.
Warum haben diese Sprachen keine unbedingten Sprünge? Weil man sie nicht
braucht - allerspätestens dann, wenn man bessere Sprachmittel zur
Verfügung hat. Und auch vorher schon kann man ohne auskommen, wenn man
will.
> Und den o.g. Ausschluss kannst du auch nicht machen (und für dieses> Beispiel auch nichts besseres bringen ohne goto).> Offensichtlich redest du nur nach, was man dir vorgibt, wie auch>>Selbstverständlich gibt es Regeln, die man als Programmierer zu>>akzeptieren hat.> zeigt.>> -------------------------------------> Und nochmal ganz allgemein:> Das Problem besteht (u.a), sobald von MEHREREN Stellen aus die Gleiche> Behandlung (oder gleiche Codeteile) ausgeführt werden sollen.
Gleiche Codeteile steckt man üblicherweise in eine eigene Funktion. Die
kann man aufrufen, von wo immer aus man will. Welchen Vorteil bringt
goto gegenüber dem Aufruf einer eigenständigen Funktion?
Yalu X. schrieb:> Michael B. schrieb:>> Bitte kann man jemand diesen Titel im ersten Beitrag ändern damit der>> eklatante Rechtschreibfehler behoben wird.>> Hab's geändert.
Danke, der Krebs ist weg.
Hier mal der Ausschnitt aus den MISRA Regeln, weil sie eine sinnhafte
Anwendung des GOTO zu beschreiben:
aus: http://archive.redlizards.com/docs/misrac2012-datasheet.pdf
Rule-15.1
The goto statement should
not be used
Advisory
Decidable
MISRAC2012-Rule-15.1
:
Uses of goto.
Rule-15.2
The goto statement shall
jump to a label declared later
in the same function
Required
Decidable
MISRAC2012-Rule-15.2
:
Backwards goto's
Rule-15.3
Any label referenced by a
goto statement shall be
declared in the same block,
or in any block enclosing the
goto statement
Required
Decidable
MISRAC2012-Rule-15.3
:
Goto's into a nested block
Rule-15.4
There should be no more
than one break or goto
statement used to terminate
any iteration statement
Advisory
Decidable
MISRAC2012-Rule-15.4
:
Two or more break or goto
statements in a loop
Rule-15.5
A function should have a
single point of exit at the end
Advisory
Decidable
MISRAC2012-Rule-15.5
:
Functions with multiple
points of exit
>M. Köhler (sylaina)>Das wäre aber jetzt auch nicht so schwer gewesen selbst zu finden.
Diese Art Kommentar kannst Du Dir grundsätzlich sparen.
steffen schrieb:> Diese Art Kommentar kannst Du Dir grundsätzlich sparen.
Da ich mir das sparen kann und nicht muss mach ich von meiner
Möglichkeit gebrauch mir solch einen Kommentar nicht zu sparen. Wenn
jemanden so etwas interessiert, ist es wirklich zuviel verlangt dass
dieser dann zumindest mal MISRA in eine Suchmaschine seiner Wahl
eingibt?
Mark B. schrieb:> Wer behauptet, dass C gut geeignet für große und komplexe SW-Projekte> sei, der dokumentiert damit dass er nicht viel Ahnung von Software hat.
Ich habe nur einen Teil Deines Postes zitiert, um quasi einen Verweis zu
haben, und nicht behauptet das C für große Projekte gut geeignet ich. Im
Gegenteil ich persönlich meide C wo es nur geht, da ich von dieser
Sprache nicht überzeugt bin. C öffnet Tür und Tor um schlecht lesbaren
und kompromitierbaren Code zu schreiben. Es würde jetzt zu weit führen
alle Features in C aufzuzählen die mir nicht gefallen, das ist auch
nicht Thema des Threads und es ist meine ganz persönliche Meinung. Im
Umkehrschluß bedeutet das jetzt nicht das alle C-Programmierer Deppen
sind die keine Ahnung von Coden haben, wie die Vielzahl (großer und
kleiner) Projekte beweist. Welche Programmiersprache man benutzt hängt
auch etwas davon ab womit man "groß" geworden ist bzw. sein erstes
größeres Projekt verwirklicht hat.
Ich hatte es schon geschrieben: Zum Schluß zählt das Endprodukt und wie
der Programmierer dahin gekommen ist, interessiert den Anwender nicht.
C verwende ich nur zur Programmierung von µC's, weil es hierfür nichts
anderes gibt, zumindest keinen guten Pascalcompiler.
Und um es gleich vorweg zu nehmen ich bin auch kein Freund von C++ und
C#. Beide basieren auf C und haben letztendlich alle Unzulänglichkeiten
von C mitgenommen. Allein die Anzahl der Zuweisungsoperatoren in C++ ist
eine Zumutung (=, -> und dann noch die Umleitungsoperatoren) sprechen
für sich, um nur mal ein Beispiel zu nennen. Alles nur irgendwie
zusammen gefrickelt. In Pascal beispielsweise gibt es nur einen einzigen
nämlich := und der gilt für alle Zuweisungen. Oder man nehme HP/HT-Basic
her, da heißt der Zuweisungsoperator -> und fertig.
Ich will jetzt die Qualität der Programmiersprache nicht am
Zuweisungsoperator fest machen, aber das ist mir jetzt gerade
eingefallen als ein Feature welches mir nicht gefällt.
C# ist auch nicht besser aber ich muß es für ein große Projekt benutzen
weil mein Arbeitgeber das wünscht.
Wie gesagt alles meine persönliche Meinung. Es darf jeder anders sehen
und jeder soll die Programmierwerkzeuge benutzen von denen er meint, daß
er damit seine Aufgaben am besten erfüllen kann und gut ist.
Jeglicher Fanatismus ist da fehl am Platze.
Zeno
M. K. schrieb:> chris_ schrieb:>>>Sie empfiehlt nur goto nicht zu verwenden, sie verbietet die>>>Verwendung aber nicht>>>> Gibt es eigentlich irgendwo im Netz ein Dokument, wo man die MISRA>> Regeln einsehen kann?>> Google ist dein Freund:> http://archive.redlizards.com/docs/misrac2012-datasheet.pdf>> Das wäre aber jetzt auch nicht so schwer gewesen selbst zu finden.
Das Datasheet ist aber leider nur die halbe Wahrheit, es listet nur auf
ohne Erläuterungen, der gesamte MISRA-C:2012 Standard hat 236 Seiten und
ist legal nur bei MISRA zu kaufen (Kostet aber nicht die Welt: GBP 15 +
VAT). Wie jemand schon gesagt hat (um mich genüsslich richtigzustellen,
hatte am WoE leider nicht den Text des Standards zur Verfügung und nur
aus dem Gedächtnis zitiert), besagt Rule 15.1 bei MISRA "The goto
statement should not be used" und ist eine sog. Advisory-Regel. Jetzt
ist das aber nicht bloß als eine Empfehlung abzukanzeln, sondern es
heißt bei MISRA (sinngemäß übersetzt, Quelle: MISRA-C:2012, Kap. 6.2.3,
S.13):
Advisory guidelines sind Empfehlungen. Das bedeutet aber nicht, dass
diese Punkte ignoriert werden können, sondern soweit als sinnvoll
möglich zu befolegen sind. Der Prozess für formale Abweichungen muss
nicht eingehalten werden, aber das Nichtbefolgen ist zu dokumentieren.
Eine Organisation kann für sich entscheiden, advisory guidelines als
mandatory zu behandeln.
Außerdem erlaubt MISRC-C goto nur unter den folgenden Bedingungen:
- nur Vorwärtssprünge sind erlaubt (Rule 15.2)
- nur Sprünge im lokalen Block sind erlaubt (Rule 15.3)
- maximal ein goto (oder break) darf eine Schleife beenden (Rule 15.4)
Das schließt meinem Dafürhalten nach Schleifenbildung mit goto definitiv
aus.
Grüsse
Herby
Herbert P. schrieb:> Das Datasheet ist aber leider nur die halbe Wahrheit...
Oh, dagegen habe ich auch nichts zu sage. Ich wollte damit nur drauf
hinweisen, dass Aussagen wie diese hier:
chris_ schrieb:> Die MISRA-Regeln verbieten es.
schlicht falsch sind.
Zum eigentlichen Thema kann ich nur sagen, dass auch ich es gelehrt
bekommen habe goto zu vermeiden. Ich bin in C aber bisher auch noch nie
in die Verlegenheit gekommen, dass ich ein goto gebraucht hätte. Es lies
sich immer vermeiden bei den Programmen, die ich schrieb. Weiter oben
jedoch, das USB-Beispiel, ist, finde ich, mit goto ein stückweit
lesbarer als mit den ineinander verschachtelter Schleifen. Was von
beiden Varianten nun aber wirklich der allgemein bessere Code ist vermag
ich nicht zu sagen.
@M. Köhler (sylaina)
>Zum eigentlichen Thema kann ich nur sagen, dass auch ich es gelehrt>bekommen habe goto zu vermeiden.
Me too. Beim Umstieg von BASIC auf Pascal in der Schule war das nicht
vorhandene bzw. nicht erlaubte GoTo erstmal ein Schock.
Meine Reaktion "Geht doch gar nicht!!!".
Und es ging doch, und das sogar problemlos.
> Ich bin in C aber bisher auch noch nie>in die Verlegenheit gekommen, dass ich ein goto gebraucht hätte. Es lies>sich immer vermeiden bei den Programmen, die ich schrieb.
Me too, wenn gleich ich nicht der große Programierer bin. Meine
Programme spielen am unteren Ende der Skala, was Umfang und Komplexität
angeht.
> Weiter oben>jedoch, das USB-Beispiel, ist, finde ich, mit goto ein stückweit>lesbarer als mit den ineinander verschachtelter Schleifen.
Du vermischt was. Im USB-Beispiel war es ein Switch, die Schleifen waren
der TCP Ausschnitt aus dem RTOS.
>Was von>beiden Varianten nun aber wirklich der allgemein bessere Code ist vermag>ich nicht zu sagen.
Das RTOS-Beispiel kommt ohe Goto spielend aus, ist sehr lesbar und mit
der Erweiterung auf eine ENDLICHE Anzahl von Suchvorgängen sogar
wasserdicht.
Das USB-Beipiel gewinnnt durch goto nur minimal an Lesbarkeit, eine
Funktion oder das Setzen eines Flags an der Stelle wären ebenso OK und
goto-frei ;-)