Ist goto ausnahmslos immer schlecht?
-
+fricky schrieb:
hartmut1164 schrieb:
Die Codition der Durchfuehrung einer Schleife sollte nur einmal definiert sein und nicht an verschiedenen Orten. Ist halt wieder ein hidden-goto.
lass mich raten - du findest es bestimmt auch doof, wenn mehr als ein 'return' aus einer funktion herausführen, oder?
In den allermeisten Faellen ja. Ich kenne nur zwei Faelle wo man das guten Gewissen machen kann:
-
Bei Recursiven Funktionen ist oft nicht zu vermeiden (um saubere Abbruchbedingungen zu haben ohne mit localen Variabken den Stack mehr belasten als ohnehin schon).
-
Wenn sich diese zum Ende der Funktion als eine Einheit darstellen.
Ansonsten hat ein return mitten in einer Funktion nichts zu suchen.
-
-
hartmut1164 schrieb:
void funcA(size_t size) { char *buffer = NULL; int some_res = 0; FILE *file = NULL; int err = 0; buffer = malloc(sizeof (char) * size); if (buffer == NULL) { fprintf (stderr, "Can't alloc mem\n"); err = 1; } else { some_res = get_sys_res(SOME_CONST); file = fopen("/the_life/the_universe/and/everything", "r"); if (file == NULL) { fprintf (stderr, "Can't open file - details: Code <%d> Mssg: <%s>\n", errno, strerror (errno)"); err = 1; } } if ((err != 0) && (do_something_with (some_res, buffer) != 0) && (do_something_else (file, some_res) != 0) && (everything_ok (buffer, file) != 0)) and_another_func(buffer, file, some_res); if (buffer != NULL) free (buffer); if (file != NULL) fclose (file ); free_sys_res(some_res); return; }
Und was ist, wenn noch 5 weitere Ressourcen benötigt werden, und nicht nur drei? Bei dieser Version geht geht die Übersicht bereits komplett flöten.
Mal davon abgesehen, wird im Fallerr != 0
munterdo_something_with (some_res, buffer)
aufgerufen, und das kann zu nichts Gutem führen, selbst wenn Du den Rückgabewert auswertest. Mitgoto
wär das nicht passiert.
-
Also, ich denke entweder ist hartmut ein codetaliban/fundamentalist oder er will uns nur verarschen. Selber schuld, wer sich seinen Code aus fundamentalistischen Gründen unleserlich und unwartbar macht.
-
hartmut1164 schrieb:
Ansonsten hat ein return mitten in einer Funktion nichts zu suchen.
Das hat mir mein Ausbilder auch noch beigebracht. Genauso wie man alle Variablen am Anfang einer Funktion deklarieren soll, globale Variablen praktisch sind und intensiv genutzt werden sollten, Funktionen ruhig mal eine drei- oder vierstellige Zeilenanzahl erreichen dürfen, usw...
-
Tachyon schrieb:
Und was ist, wenn noch 5 weitere Ressourcen benötigt werden, und nicht nur drei?
Diese werden auf dem Stack alloiert und gleich wieder freigeben; das ist nur ein Problem bei extensiven Rekursionen (oder im embedded-Bereich). Wenn die Vairablenliste groesser als 5 oder 6 wird, sollte man sich das Design der Funktion noch ueberlegen; dann wird einfach zuviel Funktionalitaet hineingeschmiert.
Das gleich gilt fuer die Laenge: Eine Funktion sollte eine Bildschirmseite nicht ueberschreiten.
Tachyon schrieb:
Mal davon abgesehen, wird im Fall
err != 0
munterdo_something_with (some_res, buffer)
aufgerufen, und das kann zu nichts Gutem führen, selbst wenn Du den Rückgabewert auswertest.Das tut er nicht: --> Sequence Point, C99-Std, Annex C und 6.5.13. - War auch Std. in den ersten Entwuerfen zu C in den fruehen 1970ern, bin aber zu faul das rauszusuchen.
-
hartmut1164 schrieb:
Wenn die Vairablenliste groesser als 5 oder 6 wird, sollte man sich das Design der Funktion noch ueberlegen; dann wird einfach zuviel Funktionalitaet hineingeschmiert.
Das ist Quark. Viele Ressourcen zu allokieren bedeutet nicht, viel Funktionalität zu haben.
hartmut1164 schrieb:
Das tut er nicht: --> Sequence Point, C99-Std, Annex C und 6.5.13. - War auch Std. in den ersten Entwuerfen zu C in den fruehen 1970ern, bin aber zu faul das rauszusuchen.
Klar tut er das. Short Circuit Evaluation ist Dir ein Begriff?
-
Tachyon schrieb:
Klar tut er das. Short Circuit Evaluation ist Dir ein Begriff?
In Pascal gibts das nicht
-
Tachyon schrieb:
hartmut1164 schrieb:
Das tut er nicht: --> Sequence Point, C99-Std, Annex C und 6.5.13. - War auch Std. in den ersten Entwuerfen zu C in den fruehen 1970ern, bin aber zu faul das rauszusuchen.
Klar tut er das. Short Circuit Evaluation ist Dir ein Begriff?
6.5.13
4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation;
there is a sequence point after the evaluation of the first operand. If the first operand
compares equal to 0, the second operand is not evaluated.http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
---
"Short circuit evalution" bedeutet, dass die nachfolgende (Teil-)Expression nicht mehr ausgewertet wird, wenn die erste (Teil-)Expression schon den Wert der Gesamtexpression determiniert. Das ist bei der &&-Sequence der Fall, da ein logisches "False" die Gesamtexpression zu "False" werden laesst.
Also hier:
if ((err != 0) && (do_something_with (some_res, buffer) != 0) && (do_something_else (file, some_res) != 0) && (everything_ok (buffer, file) != 0))
Wenn also (err != 0) ist, wird do_something etc. nicht ausgefuehrt, da es den Gesamtwert nicht mehr veraendern kann; entsprechend der Reihenfolge festgelegt in 6.5.13 der ISO9899.
-
Bashar schrieb:
Tachyon schrieb:
Klar tut er das. Short Circuit Evaluation ist Dir ein Begriff?
In Pascal gibts das nicht
Doch gibt es das in Pascal. C und Pascal benutzen hier aehnliche Techniken.
-
hartmut1164 schrieb:
Bashar schrieb:
Tachyon schrieb:
Klar tut er das. Short Circuit Evaluation ist Dir ein Begriff?
In Pascal gibts das nicht
Doch gibt es das in Pascal. C und Pascal benutzen hier aehnliche Techniken.
zeig mal nen link, der das bestätigt.
nee, habs selber gefunden.
-
Der Link würde mich ja dann doch mal interessieren. Meines Wissens spezifiziert Pascal keine Shortcut-Semantik. In Turbo Pascal kann man es ein oder ausschalten, aber ich rede nicht von Turbo Pascal.
-
hartmut1164 schrieb:
...rhabarber...
Und was kommt Deiner Meinung nach bei
err = 1
(Fehler) underr != 0
für ein Wahrheitswert heraus?hartmut1164 schrieb:
6.5.13
4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation;
there is a sequence point after the evaluation of the first operand. If the first operand
compares equal to 0, the second operand is not evaluated.Du sagst es.
-
Bashar schrieb:
Der Link würde mich ja dann doch mal interessieren. Meines Wissens spezifiziert Pascal keine Shortcut-Semantik. In Turbo Pascal kann man es ein oder ausschalten, aber ich rede nicht von Turbo Pascal.
Es abhaenig von Umgebung - Ich habe nochmal nachgeschaut; Der Annex F der ISO7185 listet die Faelle in der dies durch Implementation definiert wird. Die Technik ist die selbe, nur u.U. "verkehrt" herum. Was natuerlich nicht befriedigend ist.
-
Bashar schrieb:
Der Link würde mich ja dann doch mal interessieren. Meines Wissens spezifiziert Pascal keine Shortcut-Semantik. In Turbo Pascal kann man es ein oder ausschalten, aber ich rede nicht von Turbo Pascal.
standard-pascal läßt es offen
http://www.soe.ucsc.edu/classes/cmps203/Spring98/hw/example2.htmlDie „Short Circuit“-Funktionalität von && und || in C (sobald das Ergebnis feststeht, nämlich wenn der linke Teil beim and FALSE beziehungsweise beim or TRUE ist, wird der rechte nicht mehr ausgewertet) schloss N. Wirth explizit aus
http://de.wikipedia.org/wiki/Pascal_(Programmiersprache)GNU Pascal machts aber by default
http://www.mirrorservice.org/sites/www.gnu-pascal.de/gpc/and.html
-
Tachyon schrieb:
hartmut1164 schrieb:
...rhabarber...
Und was kommt Deiner Meinung nach bei
err = 1
(Fehler) underr != 0
für ein Wahrheitswert heraus?The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.93) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
CC99, 6.5.9.4 Equality operators, URL. s.o.
-
hartmut1164 schrieb:
Tachyon schrieb:
hartmut1164 schrieb:
...rhabarber...
Und was kommt Deiner Meinung nach bei
err = 1
(Fehler) underr != 0
für ein Wahrheitswert heraus?The == (equal to) and != (not equal to) operators are analogous to the relational operators except for their lower precedence.93) Each of the operators yields 1 if the specified relation is true and 0 if it is false. The result has type int. For any pair of operands, exactly one of the relations is true.
CC99, 6.5.9.4 Equality operators, URL. s.o.
Und? Du wirfst munter mit dem Standard um Dich, aber das
1 != 0 => true
ist, scheint Dir irgendwie nicht klar zu sein.
-
supertux schrieb:
Also, ich denke entweder ist hartmut ein codetaliban/fundamentalist oder er will uns nur verarschen. Selber schuld, wer sich seinen Code aus fundamentalistischen Gründen unleserlich und unwartbar macht.
Nein, ich vermute, er kommt/stammt aus Asien, vermutlich aus China, denn, er schreibt ja immer:
if ((err != 0) && (do_something_with (some_res, buffer) != 0) && (do_something_else (file, some_res) != 0) && (everything_ok (buffer, file) != 0)) and_another_func(buffer, file, some_res);
Aber mal im Ernst,
Bashar schrieb:
Und wenn du das alles hast sacken lassen, besinne dich auf die Realität. Im echten Leben hat man meistens Vorgesetzte, die gut Dinge organisieren können (deshalb sind sie Vorgesetzte), aber von solchen philosophischen Details keine Ahnung haben, und dir ein goto negativ ankreiden werden. Der Kampf ist längst gefochten und verloren, goto wird sein Stigma nicht mehr los.
So sieht es aus. Die Vorgesetzten entscheiden, wie der Code aussehen soll und welche Praktiken eingesetzt werden dürfen und welche nicht. Da wird ja auch nicht zwischen dem Sinn und Unsinn unterschieden. Wenn z.B. bei diesem Code
int i; for (i = 0; i < 10; i++) { ... }
von irgendeinem Tool zwei Warnungen ausgespuckt werden, 1. Variable i nicht initialisiert, 2. Ergebnis von Inkrement unbenutzt, dann stehen diese Warnungen da und müssen behoben werden
int i = 0; for (i = 0; i < 10; ++i) { ... }
Ob die Qualität der Software dadurch besser wird, sei dahingestellt, aber so kann die Realität aussehen.
-
Ist schon lustig, wie du dich mit deinem err verhaspelst. Dabei hätte es ein simples return bei file==NULL und buffer==NULL auch getan. Somit hast du exemplarisch bewiesen, dass die return-mittendrin-Methode für dich eigentlich die weniger fehleranfällige ist.
-
_matze schrieb:
Ist schon lustig, wie du dich mit deinem err verhaspelst. Dabei hätte es ein simples return bei file==NULL und buffer==NULL auch getan. Somit hast du exemplarisch bewiesen, dass die return-mittendrin-Methode für dich eigentlich die weniger fehleranfällige ist.
Und das es nichts bringt zu zeigen, dass man Copy&Paste aus der ISO/IEC 9899:1999 machen kann, wenn man den Inhalt nicht versteht.