Sauberer Programmierstil für Funktionsabbruch bei Fehler?



  • 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 Frage

    danke 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>


Anmelden zum Antworten