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; }
:
Bearbeitet durch User
>> 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.
1 | int i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START; |
2 | found = 1; |
3 | |
4 | for (; found && i>0; i--) { |
5 | if (port++ >= TCP_LOCAL_PORT_RANGE_END) { |
6 | port = TCP_LOCAL_PORT_RANGE_START; |
7 | }
|
8 | /* Check all PCB lists for port occurance */
|
9 | for (i = 0, found = 0; !found && i < NUM_TCP_PCB_LISTS; i++) { |
10 | for(pcb = *tcp_pcb_lists[i]; !found && pcb != NULL; pcb = pcb->next) { |
11 | if (pcb->local_port == port) found = 1; |
12 | }
|
13 | }
|
14 | }
|
15 | |
16 | if (i==0) { |
17 | // error, all ports are in lists
|
18 | return ERROR; |
19 | } else { |
20 | return port; // port is not in lists |
21 | }
|
Und jetzt werden die Goto-ianer wieder über die Hilfsvariable found lästern ;-)
:
Bearbeitet durch User
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.
War noch ein kleiner Fehler drin 8-0 So ist es richtig und LESBAR!!!
1 | int i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START; |
2 | found = 1; |
3 | |
4 | for (; found && i>0; i--) { |
5 | if (port++ >= TCP_LOCAL_PORT_RANGE_END) { |
6 | port = TCP_LOCAL_PORT_RANGE_START; |
7 | }
|
8 | /* Check all PCB lists for port occurance */
|
9 | for (i = 0, found = 0; !found && i < NUM_TCP_PCB_LISTS; i++) { |
10 | for(pcb = *tcp_pcb_lists[i]; !found && pcb != NULL; pcb = pcb->next) { |
11 | if (pcb->local_port == port) found = 1; |
12 | }
|
13 | }
|
14 | }
|
15 | |
16 | if (found) { |
17 | return 0; // error, all ports are in lists |
18 | } else { |
19 | return port; // port is not in lists |
20 | }
|
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.
:
Bearbeitet durch User
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:
1 | static bool port_is_in_use(u16_t port) { |
2 | struct tcp_pcb *pcb; |
3 | int i; |
4 | |
5 | for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { |
6 | for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { |
7 | if (pcb->local_port == port) |
8 | return true; |
9 | }
|
10 | }
|
11 | return false; |
12 | }
|
13 | |
14 | static u16_t tcp_new_port(void) { |
15 | static u16_t port = TCP_LOCAL_PORT_RANGE_START; |
16 | |
17 | do { |
18 | if (port++ >= TCP_LOCAL_PORT_RANGE_END) |
19 | port = TCP_LOCAL_PORT_RANGE_START; |
20 | } while(port_is_in_use(port)); |
21 | |
22 | return port; |
23 | }
|
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 |
5 | * new TCP local port. |
6 | */ |
;-)
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.
Falk B. schrieb: > War noch ein kleiner Fehler drin 8-0 > So ist es richtig fast ;-) i wird doppelt verwendet
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, ...
:
Bearbeitet durch User
@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.
:
Bearbeitet durch User
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 . . .
1 | static u16_t tcp_new_port(void) { |
2 | static u16_t port = TCP_LOCAL_PORT_RANGE_START; |
3 | u16_t i; |
4 | |
5 | for (i=0xFFFF; i>0; i--) { |
6 | if (port++ >= TCP_LOCAL_PORT_RANGE_END) { |
7 | port = TCP_LOCAL_PORT_RANGE_START; |
8 | }
|
9 | if (!port_is_in_use(port)) break; |
10 | }
|
11 | |
12 | if (i==0) { |
13 | return 0; // error, no more free ports |
14 | } else { |
15 | return port; |
16 | }
|
17 | }
|
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:
1 | u16_t i; |
2 | for( i=0; --i; ) { |
3 | ...
|
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.
Falk B. schrieb: > for (i=0xFFFF; ÄÄÄÄH waren magic Number nich schlechter Programmierstil - hat mir in diesem Thread gesagt. Zeno
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.
Schaff ich das noch heute noch?
1 | static u16_t tcp_new_port(void) { |
2 | static u16_t port = TCP_LOCAL_PORT_RANGE_START; |
3 | u16_t i = TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START; |
4 | |
5 | for (; i>0; i--) { |
6 | if (port++ >= TCP_LOCAL_PORT_RANGE_END) { |
7 | port = TCP_LOCAL_PORT_RANGE_START; |
8 | }
|
9 | if (!port_is_in_use(port)) break; |
10 | }
|
11 | |
12 | if (i==0) { |
13 | return 0; // error, no more free ports |
14 | } else { |
15 | return port; |
16 | }
|
17 | }
|
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
Ich denke es geht um soein Konstrukt?
1 | bool do_something( const char* a, const char* b ){ |
2 | |
3 | bool success = false; |
4 | |
5 | FILE* f1 = fopen(a,"r"); |
6 | if(!f1) |
7 | goto cleanup1; |
8 | |
9 | FILE* f2 = fopen(b,"w"); |
10 | if(!f2) |
11 | goto cleanup2; |
12 | |
13 | if( do_something_with_files(f1,f2) ){ |
14 | success = true; |
15 | }else{ |
16 | goto cleanup3; |
17 | }
|
18 | |
19 | cleanup3:
|
20 | fclose(f2); |
21 | cleanup2:
|
22 | fclose(f1); |
23 | cleanup1:
|
24 | return success; |
25 | }
|
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 ;)
:
Bearbeitet durch User
Daniel A. schrieb: > Na dann bin ich mal froh, das mein Konstrukt im (nicht) Fehlerfall alle > Aufräumarbeiten macht ;) Du hast es nicht verstanden.
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...
Daniel A. schrieb: > Ach so, es ging darum dass die Klammern bei try - finally verhindern, Äh wo sind bei meinem try/finally Klammern ????? Zeno
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) |
9 | end; |
Zeno
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.
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
Die Diskussion war doch von Anfang an zum scheitern verurteilt, oder hat irgendjemand seine goto-Meinung geändert? https://youtu.be/YbX0wwp-nlI
:
Bearbeitet durch User
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... ;-)
Selbst Kernigham hat es schon etwas differenzierter ausgedrueckt als in die Buchfassung hier herausgelesen wIrd: https://www.lysator.liu.se/c/bwk-tutor.html#goto
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
Vintage ist doch in. Mit goto kommt das Basic Feeling zurück. ;-)))
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
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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?
:
Bearbeitet durch User
>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?
Michael B. schrieb: > Bitte kann man jemand diesen Titel im ersten Beitrag ändern damit der > eklatante Rechtschreibfehler behoben wird. Hab's geändert.
Mark B. schrieb: > Java kennt kein goto Stimmt, aber dafür gibts benannte Blöcke. In JavaScript übrigens auch.
1 | // Sinnfreier Java/JavaScript code
|
2 | a: { |
3 | if(bla()) |
4 | break a; |
5 | bla(); |
6 | }
|
7 | |
8 | i=0; |
9 | b: do { |
10 | while(i<100) |
11 | if( i++ == 50 ) |
12 | continue b; |
13 | break; |
14 | } while(1); |
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.
>Gleiche Codeteile steckt man üblicherweise in eine eigene Funktion.
Eben nicht! Jedenfalls nicht immer.
Den Grund hatte ich schon genannt.
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
Daniel A. schrieb: > Stimmt, aber dafür gibts benannte Blöcke. In JavaScript übrigens auch. Letztendlich ein goto mit Tarnkappe. :-)
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 ;-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.