Ich habe dies in Google eingegeben, aber ich habe nur Anleitungen in C++ gefunden.
Wie kann ich das in C machen?
httpinterpretieren
Ich habe dies in Google eingegeben, aber ich habe nur Anleitungen in C++ gefunden.
Wie kann ich das in C machen?
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
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.:
FALSE
und mit a last_error
Variable oder Funktion.Sehen http://en.wikibooks.org/wiki/C_Programming/Error_handling.
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
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 long
z.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
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 long
z.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
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
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