gibt es bei C kein TRY/CATCH wie bei JAVA?
Der Programmierwolf schrieb: > gibt es bei C kein TRY/CATCH wie bei JAVA? nein, sonst währe es ja c++
Wenn ich das recht weiß, gibt es in C auch keine Exceptions. Damit braucht man auch kein try/catch. Man braucht nichts fangen, was es nicht gibt.
Aber es gibt assert. Klar, ist nicht das Gleiche aber vielleicht hilft es dir weiter! Gruß Dennis
Kaj schrieb: > Wenn ich das recht weiß, gibt es in C auch keine Exceptions. Damit > braucht man auch kein try/catch. Man braucht nichts fangen, was es nicht > gibt. Es gibt zwar kein try catch, exeptions aber, je nach Platform, schon. 0.0f/1.0f kann zu einer floating point exeption füren. Wenn du ohne nicht leben kannst, dann mach in C++ ne lib, in welcher du eine
1 | void throwFunc(void*) |
schreibst, und ein
1 | void catchFunc(void(*)(void*,void*),void*) |
, welche du in deine c Application einbindest. (Ist aber eine schlechte Idee)
Daniel A. schrieb: > Es gibt zwar kein try catch, exeptions aber, je nach Platform, schon. > 0.0f/1.0f kann zu einer floating point exeption füren. Auch wenn es exception heißt, ist es keine, die man mit irgendwelchen Sprachmitteln fangen kann. Es wird nur ein Zustand signalisiert, den man erkennen und darauf reagieren kann. In dem Zusammenhang Stack aufräumen, Destruktoren aufräumen oder andere Speilereien: Fehlanzeige.
... und damit kann man keine Exceptions wirklich nachbauen, weil die Freigabe aller Resourcen auf dem Stack bei einem longjmp() fehlt.
:
Bearbeitet durch User
Klaus Wachtler schrieb: > ... und damit kann man keine Exceptions wirklich nachbauen, weil die > Freigabe aller Resourcen auf dem Stack bei einem longjmp() fehlt. Könnte man schon, man bräuchte halt für jeden catch-Block eine setjump, müsste die Sprungziele in einer verketteten Liste auf dem Stack verknüpfen und der Reihe nach anspringen. Ressourcenfreigabe muss man in C ohnehin manuell machen, dass ließe sich in einen solchen Mechanismus integrieren. Ob sich dieser Aufwand allerdings lohnt? Immerhin hätte dieser Mechanismus den Vorteil, auch aus Signalhändlern heraus aufgerufen werden zu können, etwas was Exceptions meines Wissens nach nicht bieten.
be stucki schrieb: > Hier gibt es was zu lesen und Code: > http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html Ein schöner Beitrag, er zeigt das Prinzip, ist aber leider nicht wirklich zu Ende gedacht. Hauptproblem ist, dass der jmp_buf lokal angelegt wird, er ist also nur innerhalb der jeweiligen Funktion sichtbar und kann nur von dort angesprungen werden. Dazu reicht im Prinzip aber auch ein goto. Zweck des longjump ist es ja gerade, auch über Funktionsgrenzen hinweg aus einer (eventuell tief geschachtelten) Aufrufhierarchie zurück zu springen. Dazu müsste jmp_buf aber immer in irgendeiner Form global (erreichbar) sein.
ah8 schrieb: > Ob sich dieser Aufwand allerdings lohnt? Man könnte auch einfach C++ verwenden... > Immerhin hätte > dieser Mechanismus den Vorteil, auch aus Signalhändlern heraus > aufgerufen werden zu können, etwas was Exceptions meines Wissens nach > nicht bieten. Ob das ein Vorteil ist, wenn an irgendeiner Stelle im Code plötzlich eine "Exception" fliegen kann? signale sind eh eine antike Technik für typische Frickel-C-Programme. Bei sauberer Programmierung verwendet man Warten ala select() o.ä. und fängt alle möglichen Ursachen von Signalen explizit auf. Wenn man unbedint ein signal braucht um auf SIGCHLD oder so zu warten sollte man vielleicht lieber das Signal auf SIGIGN stellen, den Rückgabewert von select() o.ä. auswerten (errno = EINTR) und mit waitpid o.ä. den Status explizit abfragen. Dann Exceptions zu werfen zerstört nicht den kompletten Programmfluss...
Dr. Sommer schrieb: > Ob das ein Vorteil ist, wenn an irgendeiner Stelle im Code plötzlich > eine "Exception" fliegen kann? signale sind eh eine antike Technik für > typische Frickel-C-Programme. Signale haben nichts mit C zu tun. Signale sind ein Kommunikationsmittel des Unix Kernels und ja, Signale können an jeder beliebigen Stelle im Code eintreffen. Das ist sicher nicht immer schön, aber es ist nun mal so, ohne dass ich als Programmierer auch nur die Spur einer Chance habe, das zu verhindern. Mir bleibt nur, mich dieser Realität zu stellen, zum Beispiel, da sind wir einer Meinung, durch Signalhandler. Nun kann ich, je nach Signal, in einem Handler durchaus versuchen, etwas sinnvolles zu tun, meistens aber ist die einzig sinnvolle Alternative, das Programm zu beenden. Dabei kann es noch etwas aufzuräumen geben. In C++ ist das mit Exception grundsätzlich wunderbar zu machen, nur leider ist das Auslösen einer Exception in einem Signalhandler ein nicht definiertes Verhalten, mit anderen Worten, für diesen Zweck sind Exceptions nutzlos und nein, C++ (nur deswegen) zu nehmen ist in diesem Fall keine Lösung. Das Verhalten von longjump dagegen ist in einer solchen Situation sehr wohl definiert, folglich kann ich es für ein Ressourcenmanagement in solchen Fällen verwenden und ja, das ist ein Vorteil gegenüber Exceptions. Ob das nun die beste Lösung ist und ob die Vorteile die Nachteile aufwiegen, das steht natürlich auf einem ganz anderen Blatt.
ah8 schrieb: > Signale haben nichts mit C zu tun. Signale sind ein Kommunikationsmittel > des Unix Kernels Nur dass C "die" Sprache von Unix ist, und ein Gutteil des UNIX(POSIX)-API's direkt auf C gemünzt ist, wie zB execl - und eben signale. Wie viele andere Sprachen verwenden denn UNIX-Signale direkt, genau so wie in C? > und ja, Signale können an jeder beliebigen Stelle im > Code eintreffen. Das ist sicher nicht immer schön, aber es ist nun mal > so, ohne dass ich als Programmierer auch nur die Spur einer Chance habe, > das zu verhindern. SIGIGN wäre eine Möglichkeit. Oder einfach keine Exceptions im Signalhandler werfen, dann hast du das Problem nicht. > Mir bleibt nur, mich dieser Realität zu stellen, zum > Beispiel, da sind wir einer Meinung, durch Signalhandler. Nun kann ich, > je nach Signal, in einem Handler durchaus versuchen, etwas sinnvolles zu > tun, meistens aber ist die einzig sinnvolle Alternative, das Programm zu > beenden. Bei SIGCHLD, SIGWINCH, SIGALRM macht man typischerweise was ganz anderes als das Programm zu beenden... > Dabei kann es noch etwas aufzuräumen geben. Bloß, wenn du als Reaktion auf einen Signalhandler dein Programm beenden willst, dann handelt es sich vermutlich um SIGSEGV o.ä., d.h. dein Programm ist schon in einem kaputten Zustand, und dann solltest du eh nicht mehr viel Magic (longjmp/Exceptions) machen sondern möglichst "sicher" beenden... Wenn du aber noch in einem "normalen" Zustand bist und normal Beenden willst (zB SIGINT), kannst du im Signalhandler auch einfach nur ein Flag setzen und im nächsten Lauf der mainloop (select) sauber per C++ Exception beenden. > und nein, > C++ (nur deswegen) zu nehmen ist in diesem Fall keine Lösung. Wenn du ein Resourcenmanagement betreiben möchstest ist es sehr sinnvoll C++ zu verwenden, welches aufgrund von Smartpointern, Exceptions, Destruktoren ein viel einfacheres&sichereres Verwalten&Aufräumen als C ermöglicht.
Dr. Sommer schrieb: > ah8 schrieb: >> Signale haben nichts mit C zu tun. Signale sind ein Kommunikationsmittel >> des Unix Kernels > Nur dass C "die" Sprache von Unix ist, und ein Gutteil des > UNIX(POSIX)-API's direkt auf C gemünzt ist, wie zB execl - und eben > signale. Wie viele andere Sprachen verwenden denn UNIX-Signale direkt, > genau so wie in C? Jedem (!) Programm, was auf einem Unix System abgearbeitet wird, kann zu jeder (!) Zeit ein Signal gesendet werden, sei es vom Nutzer, dem Kernel oder einem anderen Prozess. Dabei spielt es absolut keine Rolle, in welcher Sprache das Programm oder das Betriebssystem geschrieben sind. Es gibt Signale, die standardmäßig ignoriert werden und solche, die zum Programmabbruch führen, mit oder ohne core-Dump. Dieses Verhalten mag angemessen sein oder nicht. Es mag Sprachen geben, die keine Sprachmittel zur Verfügung stellen, um auf Signale zu angemessen zu reagieren und es mag Anwendungen geben, bei denen das gar nicht nötig ist. Ich rede hier aber von den Fällen, wo es nötig ist und da muss ich im Zweifel eine Sprache wählen, die das kann. >> und ja, Signale können an jeder beliebigen Stelle im >> Code eintreffen. Das ist sicher nicht immer schön, aber es ist nun mal >> so, ohne dass ich als Programmierer auch nur die Spur einer Chance habe, >> das zu verhindern. > SIGIGN wäre eine Möglichkeit. Ist es nicht, zumindest keine allgemeingültige. Es sei denn, ich bin als Programmierer bereit, undefiniertes Verhalten zu akzeptieren. Das Verhalten beim Ignorieren von bestimmten Signalen (SIGFPE, SIGILL, oder SIGSEGV z.B.) ist laut POSIX Standard nämlich nicht definiert. Ich rede hier unter anderem genau von den Fällen. > Oder einfach keine Exceptions im > Signalhandler werfen, dann hast du das Problem nicht. Ich würde nie in einem Signalhandler eine Exception werfen, dass führt nämlich (je nach System, Compiler und Signal) auch zu undefiniertem Verhalten. >> Mir bleibt nur, mich dieser Realität zu stellen, zum >> Beispiel, da sind wir einer Meinung, durch Signalhandler. Nun kann ich, >> je nach Signal, in einem Handler durchaus versuchen, etwas sinnvolles zu >> tun, meistens aber ist die einzig sinnvolle Alternative, das Programm zu >> beenden. > Bei SIGCHLD, SIGWINCH, SIGALRM macht man typischerweise was ganz anderes > als das Programm zu beenden... OK, ich ändere meine Formulierung von 'meisten' in 'oft' oder meinetwegen auch 'manchmal'. Das ändert aber nichts an der grundsätzlichen Aussage, dass es Signale und Situationen gibt, in denen das Beenden des Programms die einzige sinnvolle Alternative bleibt und ein allgemeingültiges Ressourcenmanagement in der Lage sein muss, mit diesen Situationen umzugehen. >> Dabei kann es noch etwas aufzuräumen geben. > Bloß, wenn du als Reaktion auf einen Signalhandler dein Programm beenden > willst, dann handelt es sich vermutlich um SIGSEGV o.ä., d.h. dein > Programm ist schon in einem kaputten Zustand, und dann solltest du eh > nicht mehr viel Magic (longjmp/Exceptions) machen sondern möglichst > "sicher" beenden... Ein robustes Programm würde auch in solchen Situationen zumindest versuchen, essentielle Dinge noch aufzuräumen. Abgesehen davon steht nirgends in Stein gemeißelt, dass das so sein muss. Im Gegenteil, ein gutes Design würde immer versuchen, die Effekte selbst solcher Fehler lokal zu begrenzen, zumindest so lange, bis alles Wesentlich aufgeräumt ist. > Wenn du aber noch in einem "normalen" Zustand bist > und normal Beenden willst (zB SIGINT), kannst du im Signalhandler auch > einfach nur ein Flag setzen und im nächsten Lauf der mainloop (select) > sauber per C++ Exception beenden. Das Senden eines Signals sollte eigentlich (fast) nie der 'normale' Weg sein, ein Programm zu beenden. Im Gegenteil, wenn der Nutzer ein SIGINT sendet (INT steht für Interrupt = Unterbrechung), dann wird er wohl gerade nicht warten wollen bis das Programm das nächste Mal in seiner Mainloop vorbei kommt, sondern dass es sofort (!) reagiert, aus welchen Gründen auch immer. Übrigens, wenn ich dann wieder in der Mainloop ankomme, dann brauche ich keine Exception mehr, dann kann ich das Programm ganz normal beenden. Exception heißt Ausnahme und ist normalerweise – so jedenfalls meine Definition – für Situationen reserviert, die außerhalb des meiner Implementierung zu Grunde liegenden Modells liegen. Das Beenden eines Programms gehört ganz sicher nicht dazu. >> und nein, >> C++ (nur deswegen) zu nehmen ist in diesem Fall keine Lösung. > Wenn du ein Resourcenmanagement betreiben möchstest ist es sehr sinnvoll > C++ zu verwenden, welches aufgrund von Smartpointern, Exceptions, > Destruktoren ein viel einfacheres&sichereres Verwalten&Aufräumen als C > ermöglicht. Alles richtig, ich möchte auch nichts gegen C++ und sein Ressourcenmanagement gesagt haben. Ich programmiere oft und gerne in C++. Es hat aber sein Grenzen: Das Auslösen einer Exception aus einem Signalhandler heraus ist nicht portabel definiert und somit ein No Go. Wenn ich aber genau dieses Problem habe, aus einem Signalhandler heraus Ressourcenmanagement betreiben zu müssen, sind C++ Exceptions schlicht nutzlos. Punkt! Das, und nichts anderes habe ich gesagt. Wenn es keine anderen Gründe gibt, die in einem konkreten Fall für C++ sprechen, ist es folglich auch sinnlos, es zu verwenden.
> be stucki schrieb: > Hier gibt es was zu lesen und Code: > http://www.di.unipi.it/~nids/docs/longjump_try_tro... > Ein schöner Beitrag, er zeigt das Prinzip, ist aber leider nicht > wirklich zu Ende gedacht. Hauptproblem ist, dass der jmp_buf lokal > angelegt wird, er ist also nur innerhalb der jeweiligen Funktion > sichtbar und kann nur von dort angesprungen werden. es gibt noch 1000 andere Beispiele wie das in C geht: http://www.adomas.org/excc/ > Man könnte auch einfach C++ verwenden... das wäre sinnvoller, prinzipiell muß es auch in C funktionieren, wird dann halt komplizierter.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.