setjmp Programm



  • OK, dann sage ich es dir jetzt - setjmp ist "nicht gut" (sogar noch schlechter als goto).

    Zum inhaltlichen: Das Programm macht bestimmt nicht das, was es machen soll:

    int main()
    {
      if(setjmp(buf)!=0)
      {
        //hier landest du nach dem longjmp()-Aufruf
        print_error();
        mfunc();
      }
      else
      {
        //hierher kommst du nach dem regulären Ausführungspfad
        printf("Alles OK");
      }
      return 0;
    }
    
    void mfunc()
    {
      ...
      if(fehler) longjmp(buf,1);
      ...
    }
    

    Merkst du etwas? Auf dem "normalen" Ausführungspfad landest du nicht in deiner Arbeitsfunktion - also würde dieses Programm nur "Alles OK" ausgeben und sich dann beenden.

    PS: Wie willst du eigentlich nach der Behandlung des Fehlers weitermachen?



  • CStoll (off) schrieb:

    OK, dann sage ich es dir jetzt - setjmp ist "nicht gut" (sogar noch schlechter als goto).

    dann sind c++ exceptions aber auch 'nicht gut'



  • ich dachte es mir, ich lass so.
    setjmp(buf) ist doch immer != 0, oder nicht?
    Du hast doch das gleiche aufgeschrieben, nur anders ausgegeben.



  • net schrieb:

    CStoll (off) schrieb:

    OK, dann sage ich es dir jetzt - setjmp ist "nicht gut" (sogar noch schlechter als goto).

    dann sind c++ exceptions aber auch 'nicht gut'

    Ne, die laufen schließlich in einigemaßen strukturierten Bahnen - mit setjmp/goto wirfst du dagegen alle Strukturen über Bord, die du in deinem Programm aufgebaut hast

    *erinnert sich noch dunkel an die Programmierung auf dem C64*



  • maximo schrieb:

    ich dachte es mir, ich lass so.
    setjmp(buf) ist doch immer != 0, oder nicht?
    Du hast doch das gleiche aufgeschrieben, nur anders ausgegeben.

    man: setjmp:

    The sigsetjmp(), setjmp(), and _setjmp() functions save their calling environment in env. Each of these functions returns 0.

    The corresponding longjmp() functions restore the environment saved by the most recent invocation of the respective setjmp() function. They then return so that program execution continues as if the corresponding invocation of the setjmp() call had just returned the value specified by val, instead of 0.

    setjmp() gibt beim Direktaufruf 0 zurück - longjmp tut so, als ob das zugehörige setjmp den Parameterwert (!=0) zurückgegeben hätte.



  • ok, aber ich versteh nicht, wo jetzt der Fehler sitzt. Ich habs mir paar mal durchgelesen (das Kapitel) aber irgendwie kapier ich es nicht. 😞
    Kann mir bitte einer das näher erklären?

    Vielen Dank



  • Dann lies dir nochmal durch, was ich geschrieben habe: Du rufst setjmp() auf und speicherst damit den aktuellen Stack-Status. Danach beendest du das Programm (der Teil hinter dem "if(setjmp(env)!=0)" wird erst nach dem zugehörigen longjmp()-Aufruf gestartet).



  • ja das weiss ich ja. Und ausser dass diese Funktion schlecht ist, was kannst du mir zu meinem Program sagen?
    Ich wollte nur wissen, wo da der Fehler ist?



  • Soll ich es dir noch buchstabieren?

    DU HAST DIE ANWENDUNG VON SETJMP FALSCH VERSTANDEN

    (wie es richtig geht, habe ich ganz unten auf Seite 1 schon gesagt)



  • Das glaube ich auch 😞
    Du hast gesagt ich soll eigentliches_program() rausnehmen, aber dort ist doch longjmp(). Es wird dann nicht richtig funktionieren, da ich doch longjmp() brauche.



  • du sollst den Aufruf aus dem if() herausnehmen:

    int main()
    {
      if(setjmp(env)!=0)
      {
        behandle_fehler();
      }
      else
      {
        hauptprogramm();
      }
      return 0;
    }
    
    void hauptprogramm()
    {
      ...
      if(fehler) longjmp(env);
      ...
    }
    


  • Er hat gesagt dass Dein eigentliches_programm NIE ausgeführt wird weil setjmp zuerst 0 zurückgibt. Daraufhin meintest Du setjmp gäbe nicht 0 zurück.

    Seit dem sagt er Dir eigentlich dauernd dasselbe...



  • oh, ich hab das irgendwie verwechselt 😡
    Ich steh neben mir 😡
    Vielen Dank

    Hier nochmal das Programm:

    #include <stdio.h>
    #include <setjmp.h>
    
    void prog(void), fataler(void);
    
    static jmp_buf jump;
    
    int 
    main () {
    
    	if (setjmp(jump) != 0) {
    		fataler();
    
    	}
    	else
    		prog();
    
    	return 0;
    
    }
    
    void  fataler () {
    	puts("Kein fataler Fehler!\n");
    
    }
    
    void prog() {
    
    	if (fataler != 0) {
    		longjmp(jump,1);
    	printf("Programm\n");  
    	}
    	else
    		printf("Fataler Fehler aufgetreten!\n");
    	}
    


  • In dem Programm fehlt noch eine (sinnvolle) return-Anweisung in fataler() (und außerdem solltest du unterscheiden zwischen der Abfrage, ob ein Fehler aufgetreten ist (die Bedingung für den longjmp() im Hauptprogramm) und der Meldung, daß es einen Fehler gab (das, was hinter dem if(setjmp()!=0)... aufgerufen wird).



  • das kommt daraus, wenn man aus dem buch ein Programm erstellt, wo keine genauen infos gibt.
    Und ich weiss echt nicht, was du unter"eine (sinnvolle) return-Anweisung" meinst.



  • maximo schrieb:

    das kommt daraus, wenn man aus dem buch ein Programm erstellt, wo keine genauen infos gibt.
    Und ich weiss echt nicht, was du unter"eine (sinnvolle) return-Anweisung" meinst.

    Ganz einfach; main() hat ja nicht umsonst einen Rückgabetyp (int). Da steckt ja eine gewisse Absicht dahinter. Dieser Rückgabewert zeigt nämlich dem Aufrufer, ob das Programm korrekt (das ist dann im Normalfall der Wert 0) oder fehlerhaft (!= 0) ausgeführt wurde. Dies kann man z.B. in anderen Programmen nutzen (z.B. beim Aufruf mit system()) oder in Batchdateien.

    Da du in jedem Fall 0 zurücklieferst, ist dein Rückgabewert nicht sinnvoll.



  • Ich denke er meinte eher dass int falater() garkein return statement enthält 😉



  • LordJaxom schrieb:

    Ich denke er meinte eher dass int falater() garkein return statement enthält 😉

    Macht ja auch Sinn bei void ;). Aber dann wird fataler() in prog() total falsch verwendet und auch falsch aufgerufen, wodurch int und dann natürlich auch return Sinn macht :).

    Deswegen ist der Returnwert von main() trotzdem nicht sinnvoll :p .



  • maximo schrieb:

    Und ich weiss echt nicht, was du unter"eine (sinnvolle) return-Anweisung" meinst.

    Ich meinte damit deine Funktion fataler() - so, wie sie dort steht, ist sie nicht geeignet, in deinem Hauptprogramm aufgerufen zu werden.

    Zur Unterscheidung Fehler-Erkennung vs. Fehler-Behandlung: Du benötigst bei deinem Design zwei unterschiedliche Funktionen für deine Aufrufe von fataler():

    void behandle_fehler()
    {
      printf("Fehler aufgetreten");
      exit(1);
    }
    
    int erkenne_fehler()
    {
      if(/*Fehlerbedingungen*/)
        return 1;
      else
        return 0;
    }
    
    int main()
    {
      if(setjmp(env)!=0)
        behandle_fehler();
      else
        prog();
      return 0;
    }
    
    void prog()
    {
      ...
      if(erkenne_fehler())
        longjmp(env,1);
      ...
    }
    


  • ich hab mir das noch mal in ruhe angeguckt. Nun frage ich mich, was ich hier rein schreiben soll?

    if(/*Fehlerbedingungen*/)
    

    Ich hab jetzt das reingeschrieben( mir ist nix anderes eingefallen 🙂 )

    int erkenne_fehler()
    {
      if(jump != 0)
        return 1;
      else
        return 0;
    }
    

    Und ich hab das mit dem 0 und 1 bzw. TRUE und FALSE verwechselt.
    Das verwechle ich immer 😞
    Habt ihr vielleicht ne Eselsbrücke dafür? 😃


Anmelden zum Antworten