<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Mehrfach Exceptions werfen]]></title><description><![CDATA[<p>Hallo, ich beschäftige mich zur Zeit etwas näher mit der Fehlerbehandlung mittels Exceptions und den Problemen, auf die man dabei stoßen kann. Mein erstest größeres Problem ist folgendes:<br />
Wenn man in einer Funktion Objekte mit Destruktoren nutzt und diese Funktion durch eine Exception unterbrochen wird, so werden die Destruktoren der benutzten Objekte vor verlassen der Funktion aufgerufen (damit eventuell reservierter Speicher freigegeben werden kann). Nun stelle man sich aber vor, dass in einem der Destruktoren dieser Objekte wiederum eine Exception auftritt, was normalerweise kein Problem ist, nur was passiert in diesem speziellen Fall, wo bereits eine Exception in Behandlung ist? Mein Borland C++ Builder behandelt das besonders elegant: Er lässt das Programm mit einer Speicherzugriffsverletzung abstürzen.<br />
Ein Beispiel meines geschilderten Szenarios:</p>
<pre><code>class Test{
public:
  Test(void){}
  ~Test(void){throw int(10);}
};

void func(void){
  Test t;
  throw &quot;Error&quot;;
}

int main(int argc, char* argv[]){
  try{
    func();
  }catch(int i){
    printf(&quot;int\n&quot;);
  }catch(char *s){
    printf(&quot;char*\n&quot;);
  }
  return 0;
}
</code></pre>
<p>Hat jemand eine Idee, was in diesem Falle am sinnvollsten passieren sollte, oder wie andere Compiler mit dieser heiklen Situation umgehen?</p>
<p>Grüße,<br />
mm</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/210525/mehrfach-exceptions-werfen</link><generator>RSS for Node</generator><lastBuildDate>Tue, 13 Oct 2026 17:31:37 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/210525.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 11 Apr 2008 22:34:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Fri, 11 Apr 2008 22:34:11 GMT]]></title><description><![CDATA[<p>Hallo, ich beschäftige mich zur Zeit etwas näher mit der Fehlerbehandlung mittels Exceptions und den Problemen, auf die man dabei stoßen kann. Mein erstest größeres Problem ist folgendes:<br />
Wenn man in einer Funktion Objekte mit Destruktoren nutzt und diese Funktion durch eine Exception unterbrochen wird, so werden die Destruktoren der benutzten Objekte vor verlassen der Funktion aufgerufen (damit eventuell reservierter Speicher freigegeben werden kann). Nun stelle man sich aber vor, dass in einem der Destruktoren dieser Objekte wiederum eine Exception auftritt, was normalerweise kein Problem ist, nur was passiert in diesem speziellen Fall, wo bereits eine Exception in Behandlung ist? Mein Borland C++ Builder behandelt das besonders elegant: Er lässt das Programm mit einer Speicherzugriffsverletzung abstürzen.<br />
Ein Beispiel meines geschilderten Szenarios:</p>
<pre><code>class Test{
public:
  Test(void){}
  ~Test(void){throw int(10);}
};

void func(void){
  Test t;
  throw &quot;Error&quot;;
}

int main(int argc, char* argv[]){
  try{
    func();
  }catch(int i){
    printf(&quot;int\n&quot;);
  }catch(char *s){
    printf(&quot;char*\n&quot;);
  }
  return 0;
}
</code></pre>
<p>Hat jemand eine Idee, was in diesem Falle am sinnvollsten passieren sollte, oder wie andere Compiler mit dieser heiklen Situation umgehen?</p>
<p>Grüße,<br />
mm</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1490633</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1490633</guid><dc:creator><![CDATA[*mm* 0]]></dc:creator><pubDate>Fri, 11 Apr 2008 22:34:11 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Fri, 11 Apr 2008 23:00:44 GMT]]></title><description><![CDATA[<p>Falls während des Stack-Unwindings eine weitere Exception geworfen wird, wird terminate() aufgerufen, welches den terminate_handler handler aufruft. Im Allgemeinen führt das zum Abbruch des Programms, denn sinnvoll weiterarbeiten kann man in dieser Situation nicht. Grundsätzlich sollten Destruktoren niemals Exceptions werfen (es ist möglich obige Situation zu umgehen, wenn man vor dem Werfen uncaught_exception() prüft), jedenfalls ist sonst praktisch unmöglich, exceptionsicher zu programmieren. Derartige Klassen sind nicht STL-kompatibel.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1490638</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1490638</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 11 Apr 2008 23:00:44 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Sat, 12 Apr 2008 08:23:18 GMT]]></title><description><![CDATA[<p>Hm, ok, das sehe ich ein, nur es kann ja sein, dass die Exception im Destruktor nicht explizit von mir geworfen wird. Wenn ich im Destruktor irgend ein dynamisches Listen-Objekt benutze, welches eine &quot;OutOfRange&quot;-Exception wirft, oder es zu einer &quot;StackOverflow&quot;-Exception oder Ähnlichem kommt, dann würde das Problem ja ohne mein Zutun entstehen.<br />
Das würde dann ja bedeuten, dass mein Programm trotz Exception-Handling immer noch unkontrolliert terminieren kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1490678</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1490678</guid><dc:creator><![CDATA[*mm* 0]]></dc:creator><pubDate>Sat, 12 Apr 2008 08:23:18 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Sat, 12 Apr 2008 08:36:42 GMT]]></title><description><![CDATA[<p>[mm] schrieb:</p>
<blockquote>
<p>Hm, ok, das sehe ich ein, nur es kann ja sein, dass die Exception im Destruktor nicht explizit von mir geworfen wird. Wenn ich im Destruktor irgend ein dynamisches Listen-Objekt benutze, welches eine &quot;OutOfRange&quot;-Exception wirft, oder es zu einer &quot;StackOverflow&quot;-Exception oder Ähnlichem kommt, dann würde das Problem ja ohne mein Zutun entstehen.<br />
Das würde dann ja bedeuten, dass mein Programm trotz Exception-Handling immer noch unkontrolliert terminieren kann.</p>
</blockquote>
<p>Das bedeutet, dass du in Destruktoren solche Funktionen nicht aufrufen darfst oder sonst diese Exceptions fangen musst, bevor sie den Destruktor verlassen. <em>Jede</em> Technik, die zu Exceptionsicherheit führt, beruht notwendig auf einer Reihe von Operationen, die garantiert keine Exception auslösen.</p>
<pre><code class="language-cpp">class Test{
public:
  Test(void){}
  ~Test(void){try{throw &quot;null problemo&quot;;}catch(const char*){}}
};

void func(void){
  Test t;
  throw &quot;Error&quot;;
}

int main(int argc, char* argv[]){
  try{
    func();
  }catch(int i){
    printf(&quot;int\n&quot;);
  }catch(const char *s){
    printf(&quot;const char*\n&quot;);
  }
  return 0;
}
</code></pre>
<p>&quot;Falls während des Stack-Unwindings eine weitere Exception geworfen wird&quot; ist also nicht ganz präzise, korrekter ist es, zu sagen, falls eine Exception einen Destruktor verlässt, während der Stack aufgerollt wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1490680</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1490680</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sat, 12 Apr 2008 08:36:42 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Sat, 12 Apr 2008 09:40:53 GMT]]></title><description><![CDATA[<p>uncaught_exception zu prüfen, ist nicht sinnvoll, da dann ein fehler auf zwei verschiedene arten behandelt werden müsste und es situationen gibt, in denen es sicher ist, eine exception zu werfen, obwohl schon eine geworfen wurde.</p>
<p>besser ist es, eine eigene funktion à la close zu implementieren, und diese im destruktor dann so aufzurufen:</p>
<pre><code class="language-cpp">class Foo
{
public:
  ~Foo ()
  {
    try
    {
      close();
    }
    catch(...) { }
  }
};
</code></pre>
<p>siehe auch <a href="http://www.gotw.ca/gotw/047.htm" rel="nofollow">http://www.gotw.ca/gotw/047.htm</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1490706</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1490706</guid><dc:creator><![CDATA[queer_boy]]></dc:creator><pubDate>Sat, 12 Apr 2008 09:40:53 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Wed, 16 Apr 2008 00:57:48 GMT]]></title><description><![CDATA[<blockquote>
<p>&quot;Falls während des Stack-Unwindings eine weitere Exception geworfen wird&quot; ist also nicht ganz präzise, korrekter ist es, zu sagen, falls eine Exception einen Destruktor verlässt, während der Stack aufgerollt wird.</p>
</blockquote>
<p>danke für die klarstellung, da wollte ich gerade nochmal nachfragen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1492698</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1492698</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 16 Apr 2008 00:57:48 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Wed, 16 Apr 2008 07:19:59 GMT]]></title><description><![CDATA[<p>Dann danke ich euch für eure Antworten. Also führt kein Weg daran vorbei im Destruktor alle Exceptions zu fangen und zu behandeln, die dort auftreten können.</p>
<p>Aber ich habe auch mal einen Blick über den Tellerrand von C++ gewagt und geschaut wie es zB bei C# aussieht:<br />
* Da C# über einen Garbage-Collector verfügt ist nicht genau bestimmt, wann die Destruktoren aufgerufen werden (ja, die gibts auch dort), daher werden nicht behandelte Exceptions in ihnen einfach verworfen und führen nicht zum Terminieren des Programms.<br />
* Beim Stack-Unwinding kann mit Hilfe eines try{...}finally{...} Blocks zusätzlicher Code ausgeführt werden. Tritt dort eine weitere Exception auf, wird die Alte einfach überschrieben.</p>
<p>Also auch keine echte Patentlösung, aber ich finde, dass das finally-Konstrukt in C++ auch enthalten sein sollte.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1492741</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1492741</guid><dc:creator><![CDATA[*mm* 0]]></dc:creator><pubDate>Wed, 16 Apr 2008 07:19:59 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Wed, 16 Apr 2008 07:24:06 GMT]]></title><description><![CDATA[<p>[mm] schrieb:</p>
<blockquote>
<p>Also auch keine echte Patentlösung, aber ich finde, dass das finally-Konstrukt in C++ auch enthalten sein sollte.</p>
</blockquote>
<p>Ich finde, es ist aus gutem Grund nicht enthalten. Wenn man sich an den RAII-Grundsatz hält, steht sämtlicher Code, der beim Verlassen des Scopes aufgerufen werden soll, in irgendwelchen Destruktoren. Sowas ist in C# oder Java (eben wegen der unbestimmten Ausführung der Destruktoren) nicht möglich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1492745</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1492745</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Wed, 16 Apr 2008 07:24:06 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Wed, 16 Apr 2008 07:43:42 GMT]]></title><description><![CDATA[<p>Das ist ein Argument, jedoch muss man dann in C++ an einigen Stellen erhebliche Klimmzüge machen: So ist es zum Beispiel bei den Borland VCL Klassen oft nur möglich diese mittels new zu erzeugen (gibt sicher noch andere Beispiele, wo lokal dynamisch Daten angelegt werden müssen):</p>
<pre><code class="language-cpp">void func(void){
  TIniFile *ini = new TIniFile(&quot;file.ini&quot;);
  throwsExceptions();
  delete ini;
}
</code></pre>
<p>In diesem Falle ist man gezwungen die Fehlerbehandlung an dieser Stelle vorzunehmen, oder sich ein Wrapper-Objekt zu basteln, welches über einen Destruktor verfügt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1492756</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1492756</guid><dc:creator><![CDATA[*mm* 0]]></dc:creator><pubDate>Wed, 16 Apr 2008 07:43:42 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Wed, 16 Apr 2008 07:48:28 GMT]]></title><description><![CDATA[<p>[mm] schrieb:</p>
<blockquote>
<p>In diesem Falle ist man gezwungen die Fehlerbehandlung an dieser Stelle vorzunehmen, oder sich ein Wrapper-Objekt zu basteln, welches über einen Destruktor verfügt.</p>
</blockquote>
<p>Genau dafür gibt's doch Smartpointer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1492759</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1492759</guid><dc:creator><![CDATA[MFK]]></dc:creator><pubDate>Wed, 16 Apr 2008 07:48:28 GMT</pubDate></item><item><title><![CDATA[Reply to Mehrfach Exceptions werfen on Wed, 16 Apr 2008 07:50:54 GMT]]></title><description><![CDATA[<p>[mm] schrieb:</p>
<blockquote>
<p>In diesem Falle ist man gezwungen die Fehlerbehandlung an dieser Stelle vorzunehmen, oder sich ein Wrapper-Objekt zu basteln, welches über einen Destruktor verfügt.</p>
</blockquote>
<p>Hierfür gibt es in C++ bewährte Techniken, genannt Smartpointer. Deine Standardbibliothek bietet sogar einen einfachen an (auto_ptr, hat aber ein paar Nachteile), bessere gibt es in der Standarderweiterung TR1 (shared_ptr ist fast wie Garbage Collection), enthalten in boost, oder bei neueren GCCs auch frei Haus. Schau dazu mal in die Artikel-Abteilung, da gibt es was zu Smartpointern.</p>
<pre><code class="language-cpp">std::auto_ptr&lt;TIniFile&gt; ini( new TIniFile(&quot;file.ini&quot;) ); // oder std::tr1::shared_ptr
  ini-&gt;throwsExceptions();
  // nix :)
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1492761</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1492761</guid><dc:creator><![CDATA[LordJaxom]]></dc:creator><pubDate>Wed, 16 Apr 2008 07:50:54 GMT</pubDate></item></channel></rss>