setjmp Programm
-
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.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 DankHier 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?
-
CStoll (off) schrieb:
OK, dann sage ich es dir jetzt - setjmp ist "nicht gut" (sogar noch schlechter als goto).
In diesem Kontext sicher, aber es ist zuweilen doch recht nützlich, da es ähnliche Vorteile bietet wie die Exceptions in C++. Während man um goto praktisch immer herumkommt, hat setjmp() IMHO durchaus Existenzrecht.
CStoll (off) schrieb:
net schrieb:
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
Da setjmp() und Exceptions im Gegensatz zu goto meist zur Fehlerbehandlung, also im Ausnahmefall verwendet werden, ist es IMHO zu verschmerzen, daß sie den geregelten Programmfluß durcheinanderbringen. Der wesentliche Unterschied ist doch, daß longjmp() auf dem Stack gespeicherte Klassen nicht destruiert, und das fällt bei C nicht ins Gewicht.
Schlagt mich, wenn ich Unsinn rede...
-
@audacia: da bin ich auch deiner Meinung und es soll(te) ja auch nur dafür verwendet werden.
Deshalb war ich auch überrascht, dass man es mit goto vergleichen kann.
Ausserdem les ich ein Buch von Helmut Herold und das soll was heissen.
Dann hätte er auch was dazugeschrieben, finde ich. Wo bei goto, es sich überall liest ,dass es nicht gut ist. Kurz gesagt.Und schlagt mich nicht, wenn ich Unsinn rede