Wie kann ich eine Ausnahme in C auslösen?

Lesezeit: 8 Minuten

Benutzeravatar von httpinterpret
httpinterpretieren

Ich habe dies in Google eingegeben, aber ich habe nur Anleitungen in C++ gefunden.

Wie kann ich das in C machen?

  • C unterstützt keine Ausnahmebehandlung. Um eine Ausnahme in C auszulösen, müssen Sie etwas Plattformspezifisches verwenden, wie z. B. die strukturierte Ausnahmebehandlung von Win32 – aber um Ihnen dabei helfen zu können, müssen wir die Plattform kennen, die Sie interessiert.

    – Jerry Sarg

    23. Mai 2010 um 12:49 Uhr

  • … und verwenden Sie keine strukturierte Win32-Ausnahmebehandlung.

    – Brian R. Bondy

    23. Mai 2010 um 12:52 Uhr


  • Die Verwendung von setjmp() und longjmp() sollte theoretisch funktionieren, aber ich denke nicht, dass es die Mühe wert ist.

    – Joseph Quinsey

    23. Mai 2010 um 13:37 Uhr

Benutzeravatar von Brian R. Bondy
Brian R. Bondy

Es gibt keine Ausnahmen in C. In C werden die Fehler durch den Rückgabewert der Funktion, den Exit-Wert des Prozesses, Signale an den Prozess (Programmfehlersignale (GNU libc)) oder die CPU-Hardwareunterbrechung (oder andere Benachrichtigungsfehler von der CPU, falls vorhanden) (Wie der Prozessor den Fall der Division durch Null behandelt).

Ausnahmen werden jedoch in C++ und anderen Sprachen definiert. Die Ausnahmebehandlung in C++ ist im C++-Standard “S.15 Ausnahmebehandlung” spezifiziert, es gibt keinen entsprechenden Abschnitt im C-Standard.

  • In C ist also garantiert, dass es keine Ausnahmen gibt, wie?

    – httpinterpret

    23. Mai 2010 um 12:55 Uhr

  • @httpinterpret: In C ist es “garantiert”, dass es keine Ausnahmen gibt, genauso wie es “garantiert” ist, dass es keine Vorlagen oder keine Reflexion oder keine Einhörner gibt. Die Sprachspezifikation definiert so etwas einfach nicht. Es gibt jedoch setjmp/longjmp, mit denen eine Funktion ohne Rückkehr beendet werden kann. So könnten Programme ihre eigenen ausnahmeähnlichen Mechanismen bauen, wenn sie wollen, oder eine C-Implementierung könnte Erweiterungen des Standards definieren.

    – Steve Jessop

    23. Mai 2010 um 17:38 Uhr


  • Ein Programm mit main in einem .c Datei kann etwas C++ enthalten, und daher könnten Ausnahmen im Programm ausgelöst und abgefangen werden, aber die C-Code-Teile werden all dies nicht wissen, außer dass das Auslösen und Abfangen von Ausnahmen oft auf in C geschriebene Funktionen angewiesen ist, die sich in C++ befinden Bibliotheken. C wird verwendet, weil Sie die aufgerufene Funktion nicht riskieren können throw muss selbst eine Ausnahme auslösen. Es kann jedoch eine Compiler-/Bibliotheks-/Ziel-spezifische Möglichkeit geben, Ausnahmen auszulösen/abzufangen. Aber das Werfen einer Klasseninstanz wird seine eigenen Probleme haben.

    – Nategans

    23. Mai 2010 um 21:20 Uhr

  • @Steve: Bitte lass es mich wissen, wenn du eine Sprache mit Einhörnern findest, ich habe jahrelang auf so etwas gewartet.

    – Brian R. Bondy

    23. Mai 2010 um 23:03 Uhr

  • @BrianR.Bondy Hier ist eine Sprache mit Einhörnern (ich garantiere es genauso wie es in C garantiert wird)

    – Tofandel

    25. September 2014 um 19:12 Uhr

Benutzeravatar von vava
vava

In C könnten Sie die Kombination von verwenden setjmp() und longjmp() Funktionen, definiert in setjmp.h. Beispiel aus Wikipedia

#include <stdio.h>
#include <setjmp.h>

static jmp_buf buf;

void second(void) {
    printf("second\n");         // prints
    longjmp(buf,1);             // jumps back to where setjmp 
                                //   was called - making setjmp now return 1
}

void first(void) {
    second();
    printf("first\n");          // does not print
}

int main() {   
    if ( ! setjmp(buf) ) {
        first();                // when executed, setjmp returns 0
    } else {                    // when longjmp jumps back, setjmp returns 1
        printf("main");         // prints
    }

    return 0;
}

Notiz: Ich würde dir tatsächlich raten nicht sie zu verwenden, da sie mit C++ schrecklich funktionieren (Destruktoren von lokalen Objekten würden nicht aufgerufen werden) und es wirklich schwer zu verstehen ist, was vor sich geht. Geben Sie stattdessen eine Art Fehler zurück.

  • Ich habe gesehen, dass setjump/longjump in C++-Programmen nicht richtig funktioniert, selbst wenn keine Objekte zerstört werden mussten, wenn Ausnahmen verwendet wurden. Ich verwende sie selten in C-Programmen.

    – Nategans

    23. Mai 2010 um 21:25 Uhr

  • Dies war ein interessanter Ansatz mit setjmp. on-time.com/ddj0011.htm Aber ja, im Grunde müssen Sie sie selbst erfinden, wenn Sie eine Out-of-Band-Codeausführung wünschen, ohne den Stack abzuwickeln.

    – Dwayne Robinson

    29. März 2015 um 8:35 Uhr

  • Ich bin mir nicht sicher, warum die Einschränkung, sie in C++ zu verwenden, wenn es um C geht und C++ sowieso Ausnahmen hat. In jedem Fall ist es wichtig, dass das OP weiß, dass Sie immer daran denken, dass Sie die setjmp/longjmp-Implementierung daran hindern, Ihnen das Bein abzuschießen Erste müssen den Fehlerhandler besuchen (um ihn einzurichten), und dieser Fehlerhandler muss zweimal zurückkehren.

    Benutzer4229245

    30. April 2015 um 19:15 Uhr

  • Übrigens war die Ausnahmebehandlung etwas, von dem ich wirklich gehofft hatte, dass es in C11 gelandet wäre. Entgegen der landläufigen Meinung tut es das nicht benötigen OOP, um richtig zu funktionieren, und C leidet endlos unter jedem Funktionsaufruf, der eine erfordert if(). Ich kann darin keine Gefahr erkennen; kann hier noch jemand

    Benutzer4229245

    30. April 2015 um 19:19 Uhr


  • @ user4229245 Ich habe den (anekdotischen) Eindruck, dass alles, was “für Sie getan” wird, so weit wie möglich aus der c-Sprachspezifikation herausgehalten wird, um speziell c für Bare-Metal- und Maschinenprogrammierung relevant zu halten, wo selbst Status-Quo-Grundlagen wie Acht-Bit-Bytes nicht vorhanden sind Es ist nicht universell, nur meine Gedanken, ich bin kein C-Spec-Autor

    – ThorSummoner

    14. Mai 2020 um 3:06 Uhr


Da ist kein eingebaut Ausnahmemechanismus in C; du musst simulieren Ausnahmen und ihre Bedeutung. Dies wird normalerweise erreicht, indem man sich darauf verlässt setjmp und longjmp.

Es gibt einige Bibliotheken, und ich implementiere noch eine weitere. Es heißt Ausnahmen4c; es ist tragbar und kostenlos. Sie können es sich ansehen und vergleichen andere Alternativen um zu sehen, was am besten zu Ihnen passt.

  • Ich habe Ihr Codebeispiel gelesen, ich habe ein ähnliches Projekt mit einer Struktur gestartet, verwende aber eine UUID anstelle einer Zeichenfolge, um jede “Ausnahme” zu identifizieren. Dein Projekt sieht sehr vielversprechend aus.

    – umlkat

    21. August 2019 um 22:48 Uhr

  • Das Alternativen Link sollte jetzt zeigen github.com/guillermocalvo/exceptions4c/wiki/alternatives

    – Marcel Waldvogel

    30. Januar 2020 um 18:43 Uhr

  • Kennen Sie (oder jemand anderes) einen Vergleich zwischen den verschiedenen Ausnahmepaketen?

    – Marcel Waldvogel

    30. Januar 2020 um 18:44 Uhr

Das einfache alte C unterstützt Ausnahmen eigentlich nicht nativ.

Sie können alternative Fehlerbehandlungsstrategien verwenden, z. B.:

  • Rückgabe eines Fehlercodes
  • Rückkehr FALSE und mit a last_error Variable oder Funktion.

Sehen http://en.wikibooks.org/wiki/C_Programming/Error_handling.

Benutzeravatar von wcy
wcy

C kann C++-Ausnahmen auslösen. Es ist sowieso Maschinencode.

Zum Beispiel in Datei bar.c:

#include <stdlib.h>
#include <stdint.h>

extern void *__cxa_allocate_exception(size_t thrown_size);
extern void __cxa_throw (void *thrown_exception, void* *tinfo, void (*dest) (void *) );
extern void * _ZTIl; // typeinfo of long

int bar1()
{
   int64_t * p = (int64_t*)__cxa_allocate_exception(8);
   *p = 1976;
   __cxa_throw(p, &_ZTIl, 0);
  return 10;
}

Im Ordner a.cc,

#include <stdint.h>
#include <cstdio>
extern "C" int bar1();

void foo()
{
  try
  {
    bar1();
  }
  catch(int64_t x)
  {
    printf("good %ld", x);
  }
}

int main(int argc, char *argv[])
{
  foo();
  return 0;
}

Um es zu kompilieren:

gcc -o bar.o -c bar.c && g++ a.cc bar.o && ./a.out

Ausgabe

good 1976

https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html hat mehr Detailinfos über __cxa_throw.

Ich bin mir nicht sicher, ob es portabel ist oder nicht, und ich teste es mit ‘gcc-4.8.2’ unter Linux.

  • Was zum Teufel ist “_ZTIl” ??? Ich kann nirgendwo einen Hinweis darauf finden und es ist ein völliges Rätsel, wie es C-Code ermöglichen würde, Zugriff auf std::type_info zu haben. Bitte hilf mir!

    – AreusAstarte

    4. August 2018 um 0:09 Uhr

  • _ZTII meint typeinfo for longz.B echo '_ZTIl' | c++filt . Es ist das g++ Mangelschema.

    – Wcy

    4. September 2018 um 9:07 Uhr

  • und rufen Sie zur Sicherheit unbedingt das Symbol ac im catch-Block auf, um c++ so weit wie möglich zu vermeiden: P (PS, danke, dass Sie ein hervorragendes echtes Beispiel geteilt haben!)

    – ThorSummoner

    14. Mai 2020 um 3:08 Uhr


  • Die Verbindung ist unterbrochen (404).

    – Peter Mortensen

    10. Juni 2021 um 12:39 Uhr

Joes Benutzeravatar
Jo

Diese Frage ist super alt, aber ich bin gerade darüber gestolpert und dachte, ich würde eine Technik teilen: durch Null dividieren oder einen Nullzeiger dereferenzieren.

Die Frage ist einfach, wie man auslöst, nicht, wie man abfängt oder sogar, wie man eine bestimmte Art von Ausnahme auslöst. Ich hatte vor Ewigkeiten eine Situation, in der wir eine Ausnahme von C auslösen mussten, um in C++ abgefangen zu werden. Insbesondere hatten wir gelegentlich Berichte über „reine virtuelle Funktionsaufrufe“-Fehler und mussten die _purecall-Funktion der C-Laufzeitumgebung davon überzeugen, etwas auszulösen. Also fügten wir unsere eigene _purecall-Funktion hinzu, die durch Null dividiert, und Boom, wir bekamen eine Ausnahme, die wir in C++ abfangen konnten, und sogar etwas Stack-Spaß nutzen, um zu sehen, wo etwas schief gelaufen ist.

  • Was zum Teufel ist “_ZTIl” ??? Ich kann nirgendwo einen Hinweis darauf finden und es ist ein völliges Rätsel, wie es C-Code ermöglichen würde, Zugriff auf std::type_info zu haben. Bitte hilf mir!

    – AreusAstarte

    4. August 2018 um 0:09 Uhr

  • _ZTII meint typeinfo for longz.B echo '_ZTIl' | c++filt . Es ist das g++ Mangelschema.

    – Wcy

    4. September 2018 um 9:07 Uhr

  • und rufen Sie zur Sicherheit unbedingt das Symbol ac im catch-Block auf, um c++ so weit wie möglich zu vermeiden: P (PS, danke, dass Sie ein hervorragendes echtes Beispiel geteilt haben!)

    – ThorSummoner

    14. Mai 2020 um 3:08 Uhr


  • Die Verbindung ist unterbrochen (404).

    – Peter Mortensen

    10. Juni 2021 um 12:39 Uhr

Benutzeravatar von Peter Mortensen
Peter Mortensen

Unter Windows mit Microsoft Visual C++ (MSVC) gibt es __try ... __except ..., aber es ist wirklich schrecklich und Sie möchten es nicht verwenden, wenn Sie es möglicherweise vermeiden können. Besser gesagt, es gibt keine Ausnahmen.

  • Tatsächlich werden C++-Ausnahmen auch unter der Haube auf der Oberseite des SEH erstellt.

    – Kalmarius

    21. Juli 2016 um 11:18 Uhr

  • @Calmarius Was ist SEH?

    – Marcel Waldvogel

    30. Januar 2020 um 18:47 Uhr

  • @MarcelWaldvogel Strukturierte Ausnahmebehandlung (Windows-Methode zur Behandlung von CPU-Ausnahmen).

    – Kalmarius

    30. Januar 2020 um 22:37 Uhr

1423840cookie-checkWie kann ich eine Ausnahme in C auslösen?

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

Privacy policy