Sauberer Programmierstil für Funktionsabbruch bei Fehler?
-
MickroC schrieb:
(der Prof reißt mir den Kopf ab :p)
ach der typ hat doch null plan...
würd gern mal seinen mustervorschlag sehen
-
Nein das Goto-Problem löst sich oft leider nicht Automatisch.
Ich habe das Problem (in meinem Projekt) auch so gelöst und finde es persönlich gut lesbar.Edit: --
Die Argumentation gegen GOTO beruht ja hauptsächlich auf der schlechten lesbarkeit bei vielen Sprungmarken. Wenn man aber eine Sprungmarke "END" am Ende hat ist dies für mich sehr übersichtlich und gut.
-
Da die CPU extra Sprungbefehle hat spricht nichts dagegen sie auch in einer Programmiersprache zu nutzen. Wer gotos nicht zulässt gehört gesteinigt. In deinem Falle kannst du ja deine Funktion per return bei einem Fehler verlassen und als Returnwert deine Fehlernummer übergeben, die dann wieder von deinen Fehlerbehandlungsfunktionen weiterverarbeitet wird(Ausgabe, Log, Sprache etc.)
-
Dann handelt es sich an dieser Stelle bereits um ein Designproblem. Ein goto lässt sich oft genug vermeiden.
-
@gotoroot
ich denke er malloc't speicher oder öffnet eine datei, brauchts aber nur in der funktion und muß es natürlich vor verlassen wieder saubermachen.
-
assadsdas schrieb:
Dann handelt es sich an dieser Stelle bereits um ein Designproblem. Ein goto lässt sich oft genug vermeiden.
schon mal dein ding mit gcc -fdump-tree-all compiliert
-
goto ist hier am besten.
Für den Prof läßt man sich halt einen Blödsinn einfallen, wie Vicious Falcon vorgemacht hat, mit dem beide leben können.Eine weitere blöde Möglichkeit:
int functionsub(STRUKTUR_1* pa,STRUKTUR_2* pb,STRUKTUR_3* pc) { if(FALSE == KritischeFunktion1(a)) { // Fehler => abbrechen return ...; } if(FALSE == KritischeFunktion2(b)) { // Fehler => abbrechen return ...; } if(FALSE == KritischeFunktion3(c)) { // Fehler => abbrechen return ...; } { // weiterer Ablauf.... } } int function(void) { int iReturn = 0 STRUKTUR_1 a; STRUKTUR_2 b; STRUKTUR_3 c; // // Strukturen a, b, c initialisieren // int iReturn=functionsub(&a,&b,&c); // // Strukturen a, b, c deinitialisieren // return iReturn; }
Aber eine Wirkliche Lösung ist das noch nicht, weil was macht man, wenn b nicht initialisiert werden konnte? Dort doch ein goto? Oder if/else-Orgie? Oder um diesen Weg bis ans Ende zu gehen pro Struktur eine umgebende Funktion?
-
@?hm?: genau so siehts aus^^
@Vicious Falcon: das in einen do..while(0) Block zu packen gefällt mir rein vom Verständnis schon besser als mein swicht, ist aber im Prinzip das selbe...
@assadsdas/hhhhh: Das Problem ist, dass ich schon sehr viel in externe Funktionen ausgelagert habe und mit vielen Parametern arbeite. Ich finde zig Unterfunktionen, die nur einmal aufgerufen werden und nen Haufen Parameter übergeben bekommen nicht wirklich übersichtlicher (ja, Strukturen und typedefs werden schon umfangreich genutzt :p)
Habt aber prinzipiell schon Recht ggf. werde ich das auch alles nochmal in separate Files und Module auslagern, ist aber trotzdem auch eine prinzipielle Fragedanke gleich mal für die vielen schnellen Antworten!
-
Es ist im Grunde genommen das Gleiche, als wenn goto verwendet wird, das break steht für "Springe aus der Schleife", aber eben ohne das häufig verpönte goto.
Einen Vorteil hat die Sache natürlich, wenn ein Wert zurück gegeben werden soll.int fkt() { int success = 0; while(1) { if(!fkt1()) break; if(!fkt2()) break; // .. success = 1; break; // nicht vergessen } // hier aufräumen return success; }
Edit: Ob man so etwas wirklich im realen (Programmierer-)Leben verwendet, ist eine andere Sache. Wenn der Prof aber nunmal kein goto duldet, ist es wie Volkard schrieb, eine Lösung, mit der beide Seiten leben können.
-
assadsdas schrieb:
Dann handelt es sich an dieser Stelle bereits um ein Designproblem. Ein goto lässt sich oft genug vermeiden.
Ein Goto innerhalb einer Funktion ist auf jedenfall saubererer und klarer als dieses schreckliche while-kontrukt was ich hier gesehen habe. Welcher Nappel erzählt eigentlich das man goto vermeiden soll wenn es die einfachste und sauberste Lösung ist? In Assembler würde niemand auf die Idee kommen branches oder jumps zu vermeiden, warum sollte ein goto welches innerhalb derselben funktion springt besser sein als z.B dieses while oder switch case konstrukte? Wo immer sich ein goto anbietet um die Überichtlichkeit zu wahren sollte man es auch einsetzen und nicht vermeiden wo es nur geht und dann noch mit irgendwelche schleifen und breaks etc. wie schrecklich...
-
Vicious Falcon schrieb:
int fkt() { int success = 0; while(1) { if(!fkt1()) break; if(!fkt2()) break; // .. success = 1; break; // nicht vergessen } // hier aufräumen return success; }
das tuts doch dann auch oder?
return f1()&&f2()&&f3?1:0;
Vicious Falcon schrieb:
Wenn der Prof aber nunmal kein goto duldet, ist es wie Volkard schrieb, eine Lösung, mit der beide Seiten leben können.
sehe ich anders, denn meistens hat er dann auch eine chronische break phobie :p
-
?hm? schrieb:
sehe ich anders...
Es ging aber darum, anschließend auch noch aufzuräumen
.
-
Vicious Falcon schrieb:
?hm? schrieb:
sehe ich anders...
Es ging aber darum, anschließend auch noch aufzuräumen
.
wenn wutz jetzt da wär würd er dir sicher gern zeigen wie ein mit komma gespickter code das macht
-
lolr schrieb:
wenn wutz jetzt da wär würd er dir sicher gern zeigen wie ein mit komma gespickter code das macht
Ja, da bin ich gespannt...
Edit: ... und wäre überrascht
-
return (f1()&&f2()&&f3/*()*/)?(free(...), 1):0;
-
nnn schrieb:
return (f1()&&f2()&&f3/*()*/)?(free(...), 1):0;
Und es soll nur freigegeben werden, wenn alles geklappt hat ?
-
18 Antworten in ner knappen Stunde, sowas bin ich garnicht gewohnt^^
danke an alle!Das Problem hatte ich früher schon, wenn ich eine Strukur als Übergabeparameter bekommen habe und dann zig Einträge davon prüfen musste bevor ich mit der eigentlichen Funktion anfange (sowas für jede Funktion separat auszulagern ist auch so ne Sache...), nur bisher hat es sich dann mit 3-4 else if() Konstrukten noch übersichtlich lösen lassen...
Ich denke ich werde meinen Prof nochmal fragen wie er in dem Fall zu goto steht, sonst versuch ich es mit der do...while() Variante
Zu dem goto aber noch ne Frage: das ganze läuft in einer Multithreading Umgebung, kann es sein, dass es da mit solchen Sprungbefehlen zu Scherereien kommen kann auf die man achten müsste?
@nnn: Naja, halte ich jetzt nicht für besonders sauber und übersichtlich programmiert, da sind mit ehrlich gesagt 10 if else lieber:p
-
Ja es hat aber kein goto und goto macht den Code unübersichtlich da macht man doch besser sowas </ironie>