Ist goto ausnahmslos immer schlecht?
-
volkard schrieb:
rekursion funktionierte in pascal, aber nicht in basic.
in basic geht's so in etwa: http://www.olympus.net/personal/7seas/recurse.html
-
Je nach Sprache kann auch ein goto sinnvoll sein- natürlich nicht als
spaghetti - was ist den ein exec sql whenever.... - ist auch nur ein
goto oder
exec cics handle condition... ist auch ein goto
Wenn ich in eine Routine komme, und feststelle, hier brauch ich nix
zu tun, ist ein goto zum Routinenende sicherlich übersichtlicher wie
20 Klammern und 35 Ifs - ist so aus der mittlerweile 27-Jährigen
Programmentwicklung gewachsen.
-
Als ob irgendein Spacken hier die Weissheit mit Löffeln gefressen hätte und mir sagen darf was gut oder schlecht ist. Die Sprache stellt goto bereit. Jeder kann jetzt damit machen was er will.
-
dog-mom schrieb:
ungarischer schrieb:
also zur unterscheidung von pointern und daten sollte man mindestens auf ungarische notation zurueckgreifen, was immer man bezüglich der namensgebung auch sonst noch treiben mag.
warum ausgerechnet bei pointern?
weil man als anfänger nur bei pointern ohne jede compilerwarnung folgenden schweren fehler wiuederholt macht
while(a!=b) //statt while(*a!=*b)
-
ungarischer schrieb:
also zur unterscheidung von pointern und daten sollte man mindestens auf ungarische notation zurueckgreifen...
dann besser ausschreiben, also nicht sowas wie 'pRxPd' sondern 'RxPacketDescriptorPointer'. auch wenn's länglich wird, es macht den code verständlicher.
-
+fricky schrieb:
ungarischer schrieb:
also zur unterscheidung von pointern und daten sollte man mindestens auf ungarische notation zurueckgreifen...
dann besser ausschreiben, also nicht sowas wie 'pRxPd' sondern 'RxPacketDescriptorPointer'. auch wenn's länglich wird, es macht den code verständlicher.
einfach nur ein kleines p davor. also pPacketDescriptor istein pointer und PacketDescriptor ist ein kein pointer. das ist zwar schlimm, aber mir wird nicht übel davon.
-
Nichts für ungut, aber wie man seine Bezeichnet wählt, sollte jedem selbst überlassen bleiben, sofern man in sich konsistent bleibt und es keine Richtlinie gibt, die konkrete Vorgaben machen.
-
Tachyon schrieb:
Nichts für ungut, aber wie man seine Bezeichnet wählt, sollte jedem selbst überlassen bleiben, sofern man in sich konsistent bleibt und es keine Richtlinie gibt, die konkrete Vorgaben machen.
auf gar keinen fall. sonst kommt die gedankenpolizei und justiert den persönlichen geschmack neu.
-
+fricky schrieb:
sprunghaft schrieb:
Nicht für jede Schleife mit break; lässt sich eine äquivalente Schleife ohne break; erfinden.
Zumindest kann ich mir nicht vorstellen, dass das Gegenteil beweisbar wäre.warum nicht? musst einfach nur in der schleife die abbruchbedingung gewaltsam herbeiführen, beispiel:
for (s=0; s<100; s++) { if (s == 10) s = 100; // selbe wirkung wie 'break' }
und wieso sollte das besser sein?
schließlich musst du beim lesen des codes immernoch die Zeile "if(s==10)" lesen, dann sehen dass "s = 100" einen abbruch bzw eine beendigung der schleife bedeutet, was umständlicher ist als ein einfaches "break", da man sich noch die Abbruchbedingung merken muss(zugegebenerweise im allgemeinen leicht zu merken).
Break ist ein offensichtlicher Abbruch, deine Variante hingegen ein "verdeckter"
-
kingcools2 schrieb:
und wieso sollte das besser sein?
es ist nicht besser, aber irgendwer hier hatte was gegen break und continue in schleifen.
-
+fricky schrieb:
kingcools2 schrieb:
und wieso sollte das besser sein?
es ist nicht besser, aber irgendwer hier hatte was gegen break und continue in schleifen.
Ja - weil es klare Abbruchbedingungen versteckt. Die Codition der Durchfuehrung einer Schleife sollte nur einmal definiert sein und nicht an verschiedenen Orten. Ist halt wieder ein hidden-goto.
-
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?
-
+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.