Die verpönten goto´s
-
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
-
do{ status = recv(new_socket_fd, msg, sizeof(msg),0 ); if(status > 0){ readPtr(msg,status); }else if( status == 0){ }else{ //status < 0 } }while(status > 0);
sowas lässt den vorteil der goto variante verschwinden, man müßte mal testen, ob der compiler die while condition verschwinden lässt, wenn ja könnt ich mich damit schon anfreunden
-
aber das goto ist in dem Fall ganz in Ordnung ... manchmal ist ein goto zwingend oder die beste Wahl ... Goto nach vorn ist okay ... Goto ist okay, wenn keine Alternative einfacher ist.
Ich habe noch nie ein goto fuer noetig gehalten. Es gab immer eine bessere Alternative.
Damit wurde in früheren Zeiten schrecklicher Spaghetti-Code erzeugt.
Um Spaghetti-Code zu erzeugen, braucht es kein goto. Lambda, the ultimate GOTO
Die Frage ist nicht, ob gotos in diesem Fall in Ordnung sind, sondern ob der dargestellte Code eher an Spaghettis erinnert. Das tut er. Vorschlaege fuer Verbesserungen wurden bereits gemacht.
-
knivil schrieb:
aber das goto ist in dem Fall ganz in Ordnung ... manchmal ist ein goto zwingend oder die beste Wahl ... Goto nach vorn ist okay ... Goto ist okay, wenn keine Alternative einfacher ist.
Ich habe noch nie ein goto fuer noetig gehalten. Es gab immer eine bessere Alternative.
Bei der Fehlerbehandlung sind die in C oft praktisch
void foo() { allocateX(); allocateY(); if(!a()) goto cleanup; if(!b()) goto cleanup; c(); cleanup: freeX(); freeY(); }
-
Genau für solche Fehlerbehandlung, wo Code doppelt und dreifach vorhanden ist, nutze ich auch die goto´s!
-
schpätli schrieb:
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
Mein Punkt ist, dass man beides nicht messen kann. Meine Regel sollte ja auch nur eine "Faustregel" sein. Und als solche ist sie klar anwendbar.
-
earli schrieb:
Mein Punkt ist, dass man beides nicht messen kann.
Eine Abschätzung reicht.
earli schrieb:
Meine Regel sollte ja auch nur eine "Faustregel" sein. Und als solche ist sie klar anwendbar.
Mit Deiner Regel kannst Du Dir den Hintern abwischen.
-
rüdiger schrieb:
knivil schrieb:
aber das goto ist in dem Fall ganz in Ordnung ... manchmal ist ein goto zwingend oder die beste Wahl ... Goto nach vorn ist okay ... Goto ist okay, wenn keine Alternative einfacher ist.
Ich habe noch nie ein goto fuer noetig gehalten. Es gab immer eine bessere Alternative.
Bei der Fehlerbehandlung sind die in C oft praktisch
void foo() { allocateX(); allocateY(); if(!a()) goto cleanup; if(!b()) goto cleanup; c(); cleanup: freeX(); freeY(); }
Kein gutes Beispiel, da einfacher:
void foo() { allocateX(); allocateY(); if(a() && b()) c(); freeX(); freeY(); }