Was sind einige “gute” Möglichkeiten, longjmp/setjmp für die C-Fehlerbehandlung zu verwenden?

Lesezeit: 5 Minuten

Benutzer-Avatar
dubnde

Ich muss C für ein Projekt verwenden und ich denke darüber nach, es zu verwenden longjmp/setjmp für die Fehlerbehandlung, da ich denke, dass es viel einfacher sein wird, Fehler an einem zentralen Ort zu behandeln als Rückgabecodes. Ich würde mich freuen, wenn es einige Hinweise gibt, wie dies zu tun ist.

Ich bin besonders besorgt darüber, dass die Ressourcenbereinigung korrekt durchgeführt wird, wenn ein solcher Fehler auftritt.

Wie gehe ich auch mit Fehlern um, die dazu führen, dass Multithread-Programme sie verwenden?

Noch besser, gibt es eine C-Bibliothek, die bereits für die Fehler-/Ausnahmebehandlung existiert?

Benutzer-Avatar
eaanon01

Schauen Sie sich dieses Beispiel/Tutorial an:
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html

  • Wie kann mit dieser Implementierung der THROW von Funktionsaufrufen behandelt werden? Das ex_buf__ ist lokal in der Funktion, die den TRY-CATCH-Block verwendet, keine andere Funktion sieht diese Variable. Ich möchte auch globale Variablen wegen der Thread-Sicherheit vermeiden.

    – Torbatamas

    11. Januar 2021 um 15:49 Uhr

  • @torbatamas thread_local Variablen können Ihnen helfen.

    – Giovanni Cerretani

    22. Juli 2021 um 12:57 Uhr

Wenn Sie sich Sorgen um die Ressourcenbereinigung machen, müssen Sie sich ernsthaft fragen, ob longjmp() und setjmp() eine gute Idee sind.

Wenn Sie Ihr Ressourcenzuweisungssystem so entwerfen, dass Sie tatsächlich genau aufräumen können, ist es in Ordnung – aber dieses Design ist in der Regel schwierig und typischerweise unvollständig, wenn die Standardbibliotheken, die Ihr Code verwendet, selbst Ressourcen zuweisen, die müssen veröffentlicht werden. Es erfordert außergewöhnliche Sorgfalt, und da es nicht vollständig zuverlässig ist, ist es nicht für langlaufende Systeme geeignet, die möglicherweise mehrere Verwendungen der setjmp()/longjmp()-Aufrufe überstehen müssen (sie werden lecken, sich ausdehnen und schließlich verursachen Probleme).

Benutzer-Avatar
Werden

Symbian hat es implementiert Leave Mechanismus in Bezug auf longjmp() und dies dient als guter Rundgang durch alle Dinge, die Sie tun müssen.

Symbian hat einen globalen ‘Aufräumstapel’, den Sie pushen und Dinge, die bereinigt werden sollen, platzen lassen, falls ein Sprung passiert. Dies ist die manuelle Alternative zum automatischen Entladen des Stacks, das ein C++-Compiler ausführt, wenn eine C++-Ausnahme ausgelöst wird.

Symbian hatte ‘Fallgeschirre’, zu denen es herausspringen würde; diese könnten verschachtelt werden.

(Symbian hat es kürzlich in Bezug auf C++-Ausnahmen neu implementiert, aber die Schnittstelle bleibt unverändert).

Alles in allem denke ich, dass richtige C++-Ausnahmen weniger anfällig für Codierungsfehler und viel schneller sind als Ihr eigenes C-Äquivalent.

(Moderne C++-Compiler sind sehr gut darin, Ausnahmen ohne Overhead zu vermeiden, wenn sie beispielsweise nicht ausgelöst werden; longjmp() muss den Zustand aller Register und dergleichen speichern, auch wenn der Sprung später nicht gemacht wird, kann also grundsätzlich nie so schnell sein wie Ausnahmen.)

Die Verwendung von C++ als besseres C, bei dem Sie nur Ausnahmen und RAII übernehmen, wäre ein guter Weg, den Sie verwenden sollten longjmp() für eine Ausnahme-Emulation sei verlockend für Sie.

  • Bitte verwenden Sie den korrekten Namen: longjmp / setjmp, nicht ‘longjump’.

    – Piazza Adriano Varoli

    4. Mai 2009 um 12:39 Uhr

  • Danke für die Auskunft. Die Frage ist jedoch spezifisch für die Verwendung von C und nicht von C++

    – Dubnde

    4. Mai 2009 um 14:13 Uhr

  • @MeThinks, das ist in Ordnung, mein Rat gilt für C; Ich habe die Simulation des Stack-Unwinding (z. B. des Cleanup Stack von Symbian) skizziert, wie Sie die Ressourcenbereinigung durchführen, die Sie in Ihrer Frage gestellt haben.

    – Werden

    4. Mai 2009 um 15:51 Uhr

Benutzer-Avatar
paxdiablo

Ich habe immer nur gefunden eines verwenden für setjmp()/longjmp() und es hatte nichts mit der Fehlerbehandlung zu tun.

Es ist wirklich nicht nötig, es dafür zu verwenden, da es immer in etwas einfacher zu Befolgendes umgestaltet werden kann. Die Verwendung von setjmp()/longjmp() ist sehr ähnlich goto dadurch, dass es leicht missbraucht werden kann. Alles, was Ihren Code weniger lesbar macht, ist im Allgemeinen eine schlechte Idee. Beachten Sie, dass ich nicht sage, dass sie von Natur aus schlecht sind, sondern dass sie einfacher als die Alternativen zu schlechtem Code führen können.

FWIW, der einzige Ort, an dem sie von unschätzbarem Wert waren, war ein Projekt, das ich in den frühen Tagen der Branche (MS-DOS 6-Zeitrahmen) durchgeführt habe. Ich habe es geschafft, eine kooperative Multithreading-Bibliothek mit Turbo C zusammenzustellen, die diese Funktionen in a verwendet yield() Funktion zum Wechseln von Aufgaben.

Ich bin mir ziemlich sicher, dass ich sie seit jenen Tagen nicht mehr berührt habe (oder das Bedürfnis dazu hatte).

Ausnahmen sind bei weitem ein besserer allgemeiner Mechanismus, aber in den tiefdunklen Tagen der C-Vergangenheit habe ich einen Prozessoremulator geschrieben, der eine Befehlsshell enthielt. Die Shell, die verwendet wird, um jmp/longjmp für die Unterbrechungsbehandlung zu setzen (dh der Prozessor läuft und der Benutzer drückt break/ctrl-c, der Code fängt SIGINT und longjmps zurück zur Shell).

Benutzer-Avatar
Norman Grau

Ich habe verwendet setjmp/longjmp halbwegs ordentlich, um einem Rückruf zu entkommen, ohne mich durch diverse andere Bibliotheksebenen hocharbeiten zu müssen.

In diesem Fall (wenn ich mich richtig erinnere) konnte ein Code in einem von yacc generierten Parser ein (nicht syntaktisches) Problem erkennen und wollte die Analyse aufgeben, aber dem Aufrufer auf der anderen Seite einen einigermaßen nützlichen Fehlerbericht zurückgeben der gesamte von yacc generierte Code. Ein weiteres Beispiel war ein Callback, der von einem Expat-Parser aufgerufen wurde. In jedem Fall gab es andere Möglichkeiten, dies zu tun, aber sie schienen umständlicher und undurchsichtiger, als einfach auf diese Weise auszusteigen.

Wie andere Antworten bereits betont haben, ist es jedoch notwendig, bei der Bereinigung vorsichtig zu sein und sehr sorgfältig darauf zu achten, dass die longjmp Code ist nur innerhalb des Bereichs aufrufbar, der dynamisch durch die geschützt ist setjmp.

Tun Sie es im Kontext der Multithread-Programmierung? Ich bin sicher, das ist nicht unmöglich, aber Oooh: Hol jetzt deine Familienpackung Aspirin raus. Es ist wahrscheinlich ratsam, die zu behalten setjmp/longjmp Paare möglichst dicht beieinander. Solange eine Übereinstimmung setjmp/longjmp Paar sind innerhalb desselben Threads, ich gehe davon aus, dass Sie in Ordnung sein werden, aber … seien Sie vorsichtig da draußen.

1248050cookie-checkWas sind einige “gute” Möglichkeiten, longjmp/setjmp für die C-Fehlerbehandlung zu verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy