<?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[Exception Auftreten im Destruktor]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich habe hier ein ziemlich doofes Problem. Im Prinzip lässt es sich auf folgendes Konstrukt runterbrechen:</p>
<pre><code>class ScopedTransaction 
{
   DatabaseDAC* db_;
public:
   ScopedTransaction ( DatabaseDAC* db ) : db_( db )
   {
      assert( db_ );
      begin();
   }

   ~ScopedTransaction ()
   {
      rollback();
   }

   void begin()
   {
      if( db_-&gt;connected() ) db_-&gt;StartTransaction();
   }

   void commit()
   {
      if( db_-&gt;connected() ) db_-&gt;Commit();
   }

   void rollback()
   {
      if( db_-&gt;connected() ) db_-&gt;Rollback();
   }
};

void func( DatabaseDAC* db )
{
   try
   {
      ScopedTransaction ST( db );

      // SQL Zeugs hier
      g.commit();
   }
   catch( runtime_error&amp; rte )
   {
   }
}
</code></pre>
<p>Wenn in der Funktion <code>func</code> innerhalb des try-catch-Blocks eine Exception auftritt wird vor dem Sprung in den Exception Handler der Destruktor von <code>ScopedTransaction</code> aufgerufen. Der wirft selbst wiederum eine Exception und läuft dadurch in unendliche Rekursion und schließlich in einen Stack Überlauf.<br />
Das Problem tritt auf, wenn innerhalb der Transaktion die Verbindung zur db verloren geht. Eins der SQL Statements schlägt fehl und wirft eine Exception. Dann werden alle Variablen im try-catch Block zerstört, was zur Folge hat, dass im Destruktor von <code>ScopedTransaction</code> ein Rollback ausgeführt werden soll. Dummerweise liefert <code>db_-&gt;connected()</code> noch <code>true</code> zurück, sodass erneut eine Exception geworfen wird und zu dem Stack Overflow führt.<br />
Wie kriegt man sowas in den Griff?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/339948/exception-auftreten-im-destruktor</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 13:55:00 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/339948.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 10 Oct 2016 09:45:48 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Exception Auftreten im Destruktor on Mon, 10 Oct 2016 09:45:48 GMT]]></title><description><![CDATA[<p>Hallo zusammen,</p>
<p>ich habe hier ein ziemlich doofes Problem. Im Prinzip lässt es sich auf folgendes Konstrukt runterbrechen:</p>
<pre><code>class ScopedTransaction 
{
   DatabaseDAC* db_;
public:
   ScopedTransaction ( DatabaseDAC* db ) : db_( db )
   {
      assert( db_ );
      begin();
   }

   ~ScopedTransaction ()
   {
      rollback();
   }

   void begin()
   {
      if( db_-&gt;connected() ) db_-&gt;StartTransaction();
   }

   void commit()
   {
      if( db_-&gt;connected() ) db_-&gt;Commit();
   }

   void rollback()
   {
      if( db_-&gt;connected() ) db_-&gt;Rollback();
   }
};

void func( DatabaseDAC* db )
{
   try
   {
      ScopedTransaction ST( db );

      // SQL Zeugs hier
      g.commit();
   }
   catch( runtime_error&amp; rte )
   {
   }
}
</code></pre>
<p>Wenn in der Funktion <code>func</code> innerhalb des try-catch-Blocks eine Exception auftritt wird vor dem Sprung in den Exception Handler der Destruktor von <code>ScopedTransaction</code> aufgerufen. Der wirft selbst wiederum eine Exception und läuft dadurch in unendliche Rekursion und schließlich in einen Stack Überlauf.<br />
Das Problem tritt auf, wenn innerhalb der Transaktion die Verbindung zur db verloren geht. Eins der SQL Statements schlägt fehl und wirft eine Exception. Dann werden alle Variablen im try-catch Block zerstört, was zur Folge hat, dass im Destruktor von <code>ScopedTransaction</code> ein Rollback ausgeführt werden soll. Dummerweise liefert <code>db_-&gt;connected()</code> noch <code>true</code> zurück, sodass erneut eine Exception geworfen wird und zu dem Stack Overflow führt.<br />
Wie kriegt man sowas in den Griff?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2511089</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2511089</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Mon, 10 Oct 2016 09:45:48 GMT</pubDate></item><item><title><![CDATA[Reply to Exception Auftreten im Destruktor on Mon, 10 Oct 2016 09:54:16 GMT]]></title><description><![CDATA[<p>Wenn während der Exceptionbehandlung eine Exception geworfen wird, sollte std::terminate aufgerufen werden (was in diesem Fall vermutlich richtig wäre). Eigentlich kann es da keine Rekursion geben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2511091</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2511091</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Mon, 10 Oct 2016 09:54:16 GMT</pubDate></item><item><title><![CDATA[Reply to Exception Auftreten im Destruktor on Mon, 10 Oct 2016 10:01:26 GMT]]></title><description><![CDATA[<p>Gut möglich, dass sich unser Compiler da nicht an den Standard hält, der ist ja schließlich von Borland/Embarcadero. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Wenn <code>std::terminate</code> aufgerufen wird ist da vermutlich wirklich nicht mehr viel zu machen :(. Durch Setzen eines terminate-Handlers kann ich höchstens noch beweisen, dass der Abbruch durch diesen Mechanismus erfolgt ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2511097</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2511097</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Mon, 10 Oct 2016 10:01:26 GMT</pubDate></item><item><title><![CDATA[Reply to Exception Auftreten im Destruktor on Mon, 10 Oct 2016 10:08:38 GMT]]></title><description><![CDATA[<p>Du kannst es natürlich mit <a href="http://en.cppreference.com/w/cpp/error/uncaught_exception" rel="nofollow">http://en.cppreference.com/w/cpp/error/uncaught_exception</a> probieren, falls der Compiler das beherrscht. Ist nur die Frage, ob man in so einem Fall noch sinnvoll weitermachen kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2511099</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2511099</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Mon, 10 Oct 2016 10:08:38 GMT</pubDate></item><item><title><![CDATA[Reply to Exception Auftreten im Destruktor on Mon, 10 Oct 2016 10:30:51 GMT]]></title><description><![CDATA[<p>Hallo DocShoe,</p>
<p><a href="http://www.gotw.ca/gotw/047.htm" rel="nofollow">Herb Sutter schlägt vor</a>, die Exception innerhalb des Destruktor abzufangen.</p>
<pre><code>~ScopedTransaction ()
   {
      try {
         rollback();
      } catch(...) {
      }
   }
</code></pre>
<p>von uncaught_exception rät er ab.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2511101</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2511101</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Mon, 10 Oct 2016 10:30:51 GMT</pubDate></item><item><title><![CDATA[Reply to Exception Auftreten im Destruktor on Mon, 10 Oct 2016 11:50:09 GMT]]></title><description><![CDATA[<p>Danke Werner, auf diese Idee bin ich auch schon gekommen. Ich meine, dass sie nicht funktioniert hat und habe geglaubt, dass das iwie mit dem Stack Unwinding zu tun hat. Muss ich vllt doch noch mal genauer untersuchen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2511112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2511112</guid><dc:creator><![CDATA[DocShoe]]></dc:creator><pubDate>Mon, 10 Oct 2016 11:50:09 GMT</pubDate></item></channel></rss>