Die verpönten goto´s
-
Das SUchen in eine andere Funktion stopfigen und bei Findung dort herausreturnigen.
-
Klar kann und sollte man goto's vermeiden. Damit wurde in früheren Zeiten schrecklicher Spaghetti-Code erzeugt. Wenn goto, dann - wie gezeigt - nur ans Ende einer Funktion und nicht wild vor und zurück. Gebrauche ich auch manchmal, um aus sonst unübersichtlichen Iterationen auszusteigen. Macht dann sogar Sinn.
-
uiuiui goto Diskussion ich bin dabei... leider erstmal mit nem kontra Argument, naja wobei
int fn_a(...){ for(x= 0; x < FOO; x++) { if(array[x]) { for(y= 0; y < BAR; y++) { if(foobar[y]) return y; } } } return -1; } void fn_b(...){ if(something > 0) { if(fn_a(...)==-1) return 0; }else{ ... } ... return 1; }
Hab heut deswegen schon mal einen auf die Mütze bekommen. Nachdem ich nen goto Fetish hab tu ich mich auch ein bischen schwer da ne andere Lösung zu suchen, wills aber mal versuchen;)
Btw. ich wüßte mal gern ob es ein Konstrukt gibt, dass sich nicht ohne goto lösen lässt, das wär mir fast mal nen contest wert, nur das ich dann allen goto gegnern ein stückchen goto hinwerfen kann das sie ohne nicht nachbauen können
lg lolo
-
ups wo bin ich nur mit meinen Gedanken, z.12 muß natürlich ein int zurück geben, liegt evtl. an dem Aufwand den ich für die groß und Klein schreibung betreiben muß
-
noobLolo schrieb:
Btw. ich wüßte mal gern ob es ein Konstrukt gibt, dass sich nicht ohne goto lösen lässt
Gibt's nicht.
-
Also das mit in eine Funktion auslagern ist aus 2 Gründen "weniger schön". 1. muss ich dann trotzdem wieder den Rückgabewert prüfen, ob ich weiter mache oder nen Fehler zurück gebe und dann kommt noch dazu, das ich x und y noch brauche!
@noobLoLo
Ich behaupte mal das man jedes goto vermeiden kann, aber dann nur über extra Variablen die dir den Zustand angeben. Um es an meinem Code mal zu verdeutlichen:
if(something > 0) { for(x= 0; x < FOO && !finished; x++) { if(array[x]) { for(y= 0; y < BAR && !finished; y++) { if(foobar[y]) finished= 1; } } } if(!finished) return 0; } else { ... } go_on: ... return 1;
Aber je nachdem wie groß die Iteration ist, ist mir der Overhead aber zu groß!
-
FlashBurn schrieb:
Also das mit in eine Funktion auslagern ist aus 2 Gründen "weniger schön". 1. muss ich dann trotzdem wieder den Rückgabewert prüfen, ob ich weiter mache oder nen Fehler zurück gebe und dann kommt noch dazu, das ich x und y noch brauche!
Probier's doch mal aus! Die leitende Forderung hier ist "Ein Zweck -> eine Funktion" und die vereinfacht ganz zwanglos den großen Oschi.
-
FlashBurn schrieb:
Also das mit in eine Funktion auslagern ist aus 2 Gründen "weniger schön". 1. muss ich dann trotzdem wieder den Rückgabewert prüfen, ob ich weiter mache oder nen Fehler zurück gebe und dann kommt noch dazu, das ich x und y noch brauche!
Du kannst ja x und y zurückgeben. Der große Vorteil von Funktionen ist einfach, dass sie den Code leserlicher machen, da man direkt eine Gliederung hat. Wenn jemand nun versucht deinen Code zu verstehen und du hast da ne komplizierte Schleife, dann muss man die erst einmal nachvollziehen. Aber wenn das nun ersetzt wird durch eine entsprechend gut benannte Funktion ersetzt wird (ala find_...), dann muss man sich nicht mehr die Mühe machen, die Schleife zu verstehen.
FlashBurn schrieb:
Aber je nachdem wie groß die Iteration ist, ist mir der Overhead aber zu groß!
Hast du das nachgemessen oder vermutest du das?
Das
&& !finished
in der inneren Schleife könntest du sogar noch loswerden, wenn du direkt ein break benutzt.
-
µngbd schrieb:
noobLolo schrieb:
Btw. ich wüßte mal gern ob es ein Konstrukt gibt, dass sich nicht ohne goto lösen lässt
Gibt's nicht.:)
Ja, manchmal ist ein goto zwingend oder die beste Wahl. Anderenfalls hätte man diese Möglichkeit abschaffen können. Einsatz selten, dann aber sauber und gut kommentiert!
daddeldu
-
rüdiger schrieb:
Hast du das nachgemessen oder vermutest du das?
Ich vermute es nur, aber ich denke mal das ich da richtig liege, da ich ungefähr weiß wie der Assembler Code aussieht (als Assemblerprogrammierer hat man es ohnehin oft schwer die goto´s los zu werden, die kommen immer einfach so
). Es geht mir in dem Fall um den Worstcase. Da der Code innerhalb eines kritischen Bereichs, wo auch noch die Interrupts aus sind, ausgeführt wird, sollte er so schnell wie möglich sein.
Ich werd mir mal überlegen, ob ich das ganze in eine Funktion auslagere und wie ich das dann mit x und y mache (ob ich die Adressen übergebe oder einfach x und y in einen int reinpacke).
rüdiger schrieb:
Du kannst ja x und y zurückgeben. Der große Vorteil von Funktionen ist einfach, dass sie den Code leserlicher machen, da man direkt eine Gliederung hat. Wenn jemand nun versucht deinen Code zu verstehen und du hast da ne komplizierte Schleife, dann muss man die erst einmal nachvollziehen. Aber wenn das nun ersetzt wird durch eine entsprechend gut benannte Funktion ersetzt wird (ala find_...), dann muss man sich nicht mehr die Mühe machen, die Schleife zu verstehen.
Dem halte ich jetzt mal entgegen, dann reicht auch ein Kommentar der sagt, das ich was bestimmtes suche. Denn der ist genauso gut wie ein Funktionsname wenn man sich die Funktion dann eh nicht anguckt!
-
berniebutt schrieb:
Ja, manchmal ist ein goto zwingend
Nö.
berniebutt schrieb:
oder die beste Wahl.
Finde ich auch.
berniebutt schrieb:
Anderenfalls hätte man diese Möglichkeit abschaffen können. Einsatz selten, dann aber sauber und gut kommentiert!
daddelduOder wenn du eine Assembler-Routine aus TAOCP schnell mal abschreiben willst.
-
Oft lagert man aus, und geht dabei davon aus, daß der Compiler die Mini-Funktion wieder einlagert. (Aber ein 2d-Array durchsuchen, das ist doch schon ein Brocken von mehreren tausen Takten, da sollte der Funktionsaufruf nicht mehr ins Gewicht fallen.) Damit ist es nicht mehr so extrem wichtig, wie die Übergabe geschieht, ob über Zeiger oder so. Eigentlich bleiben es ja die beiden Variablen in der äußeren Funktion und eigentlich bleibt die Schleife drinnen, nur darfst Du die Suchfunktion woanders ausfiormulierenm.
-
volkard schrieb:
Aber ein 2d-Array durchsuchen, das ist doch schon ein Brocken von mehreren tausen Takten, da sollte der Funktionsaufruf nicht mehr ins Gewicht fallen.
Das Inlining kannst du ja auch einfach befehlen. Dann bleibt als Overhead nur mehr die Prüfung der Rückgabe, oder?
-
µngbd schrieb:
volkard schrieb:
Aber ein 2d-Array durchsuchen, das ist doch schon ein Brocken von mehreren tausen Takten, da sollte der Funktionsaufruf nicht mehr ins Gewicht fallen.
Das Inlining kannst du ja auch einfach befehlen. Dann bleibt als Overhead nur mehr die Prüfung der Rückgabe, oder?
Ja. Aber da geinlined, sieht der Optimierer wohl die Nutzlosigkeit einer Hilfsvariablen ein und macht den goto-Trick oder was ähnliches. Also nicht erst die Rückgabe in eine Variable tun.
-
Kurze Faustregel:
Goto nach vorn ist okay (wenn keine Alternative einfacher ist), goto zurück ist böse.
-
earli schrieb:
Kurze Faustregel:
Goto nach vorn ist okay (wenn keine Alternative einfacher ist), goto zurück ist böse.Goto ist dann OK, wenn es die Lesbarkeit des Codes verbessert, oder zumindest nicht verschlechtert.
-
schpätli schrieb:
earli schrieb:
Kurze Faustregel:
Goto nach vorn ist okay (wenn keine Alternative einfacher ist), goto zurück ist böse.Goto ist dann OK, wenn es die Lesbarkeit des Codes verbessert, oder zumindest nicht verschlechtert.
Deine Regel lässt sich einfach hinschreiben, aber überhaupt nicht umsetzen.
Toller Satz: "Goto ist dann lesbarer, wenn es den Code lesbarer macht."
> http://xkcd.com/703/
-
earli schrieb:
schpätli schrieb:
earli schrieb:
Kurze Faustregel:
Goto nach vorn ist okay (wenn keine Alternative einfacher ist), goto zurück ist böse.Goto ist dann OK, wenn es die Lesbarkeit des Codes verbessert, oder zumindest nicht verschlechtert.
Deine Regel lässt sich einfach hinschreiben, aber überhaupt nicht umsetzen.
Toller Satz: "Goto ist dann lesbarer, wenn es den Code lesbarer macht."
> http://xkcd.com/703/Ist nur Deine eigene Regel (Goto rückwärts ist eh indiskutablel):
"Goto ist okay, wenn keine Alternative einfacher ist."
-
earli schrieb:
Toller Satz: "Goto ist dann lesbarer, wenn es den Code lesbarer macht."
> http://xkcd.com/703/Ich habe das nicht geschrieben?
Lesbarkeit: | Schlecher | Gleich | Besser ------------------------------------------ Goto OK?: | Nein | Ja | Ja
Komplexität: | Höher | Gleich | Geringer ---------------------------------------- Goto OK?: | Nein | Nein | Ja
-
while(1){ status = recv(new_socket_fd, msg, sizeof(msg),0 ); if(status > 0){ readPtr(msg,status); continue; }else if( status == 0){ }else{ //status < 0 } break; }
loop: status = recv(new_socket_fd, msg, sizeof(msg),0 ); if(status > 0){ readPtr(msg,status); goto loop; }else if( status == 0){ }else{ //status < 0 }
bedeutet für mich 18,2% bzw. 12,5% weniger Einkommen nach dem klassischen Cocomo Model, eigentlich habt ihr ja Recht, man soll sich nicht selbst ins Knie schießen
lg lolo