<?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[Exceptions im statisch aufgerufenem Konstruktor]]></title><description><![CDATA[<p>Hallo!<br />
Ich wollte mich für meine Winsock-Library ein bisschen von boost::asio inspirieren lassen, besonders was die Initialisierung von Winsock angeht.<br />
Es muss eine Startup() und eine Cleanup()-Funktion aufgerufen werden, um mit der API zu arbeiten. boost hat das abstrahiert und lässt das statische Objekte machen:</p>
<pre><code class="language-cpp">struct A {
   A() { Startup(); }
   ~A() { Cleanup(); }
   static A a;
};

A A::a;
</code></pre>
<p>So eine ähnliche Idee hatte ich auch. Allerdings nutze ich (und boost auch) Exceptions als Fehlermechanismus, und asio benutzt eine Exception innerhalb des Konstruktors.<br />
Das führt doch immer zu std::abort(), da die Exception nicht gefangen werden kann. Ist das ein Fehler von asio o. nur meine Unwissenheit?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/281165/exceptions-im-statisch-aufgerufenem-konstruktor</link><generator>RSS for Node</generator><lastBuildDate>Sun, 23 Aug 2026 20:44:26 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/281165.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 27 Jan 2011 17:15:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Thu, 27 Jan 2011 17:15:05 GMT]]></title><description><![CDATA[<p>Hallo!<br />
Ich wollte mich für meine Winsock-Library ein bisschen von boost::asio inspirieren lassen, besonders was die Initialisierung von Winsock angeht.<br />
Es muss eine Startup() und eine Cleanup()-Funktion aufgerufen werden, um mit der API zu arbeiten. boost hat das abstrahiert und lässt das statische Objekte machen:</p>
<pre><code class="language-cpp">struct A {
   A() { Startup(); }
   ~A() { Cleanup(); }
   static A a;
};

A A::a;
</code></pre>
<p>So eine ähnliche Idee hatte ich auch. Allerdings nutze ich (und boost auch) Exceptions als Fehlermechanismus, und asio benutzt eine Exception innerhalb des Konstruktors.<br />
Das führt doch immer zu std::abort(), da die Exception nicht gefangen werden kann. Ist das ein Fehler von asio o. nur meine Unwissenheit?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013228</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013228</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 27 Jan 2011 17:15:05 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Thu, 27 Jan 2011 17:33:53 GMT]]></title><description><![CDATA[<p>Warum weichst du denn nicht auf einen anderen Fehlerbehandlungsmechanismus aus?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013241</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013241</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 27 Jan 2011 17:33:53 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Thu, 27 Jan 2011 17:55:17 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; Warum weichst du denn nicht auf einen anderen Fehlerbehandlungsmechanismus aus?</p>
</blockquote>
<p>Ich bin da leider etwas unkreativ, weil mir einfach keiner einfällt, der funktionieren könnte:</p>
<ul>
<li>Exceptions können natürlich nicht klappen (in &lt;boost/asio/detail/winsock_init.hpp&gt; wird's trotzdem getan)</li>
<li>Return-Codes kann ich nicht auswerten, da der User nichts aufruft</li>
</ul>
<p>Mir viele höchstens soetwas hässliches ein:</p>
<pre><code class="language-cpp">struct A {
   A() { 
     if(Startup())
        initialised = true;
   }

   ~A() { 
     if(Cleanup() == false) 
        // Was jetzt?
   }

   static bool initialised;
   static A a;
};

bool A::initialised = false;
A A::a;

int main() {
   // Hässlich
   if(!A::initialised)
      throw std::exception(&quot;error&quot;);
   // Nur kann ich jetzt nicht prüfen, ob Cleanup klappt)
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2013250</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013250</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 27 Jan 2011 17:55:17 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Thu, 27 Jan 2011 18:04:02 GMT]]></title><description><![CDATA[<blockquote>
<p>Exception innerhalb des Konstruktors.<br />
Das führt doch immer zu std::abort(), da die Exception nicht gefangen werden kann.</p>
</blockquote>
<p>Meinst du nicht eher eine Exception innerhalb des Destruktors. Innerhalb des Konstruktors sind Exceptions doch kein Problem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013254</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013254</guid><dc:creator><![CDATA[Verwirrt]]></dc:creator><pubDate>Thu, 27 Jan 2011 18:04:02 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Thu, 27 Jan 2011 18:07:44 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; Innerhalb des Konstruktors sind Exceptions doch kein Problem.</p>
</blockquote>
<p>Gewöhnlich nicht, nein. Aber hier schon. Schau mal auf Zeile 17. Das ist ein Konstruktoraufruf. Nur, der findet im globalen Scope statt (!).<br />
D.h., dass noch vor main() Code ausgeführt wird. Wenn ich in diesem Code eine Exception werfe, kann sie nicht gefangen werden, und das endet immer in std::abort().</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013256</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013256</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Thu, 27 Jan 2011 18:07:44 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 10:32:43 GMT]]></title><description><![CDATA[<p>Ich sehe folgende Möglichkeiten:</p>
<p>a) du lässt es dabei, dass abort() aufgerufen wird - wenn es etwas sehr wichtiges ist, ohne das das Programm eh nicht laufen kann, dann reichts, da noch ne Fehlermeldung auszuspucken (function scope try/catch um den Ctor) und dann das Programm ins abort laufen zu lassen.</p>
<p>b) Du rufst den Ctor später auf - die Methoden, die sich drauf verlassen müssen, dass Startup() bereits aufgerufen wurde, rufen eine Statische Methode von A auf, die die Initialisierung übernimmt:</p>
<pre><code class="language-cpp">class A
{
  A() {Startup();}
  ~A() {Cleanup()}

public:
  static void initialize() 
  {
    static A const a;
  }
};

void some_foo_that_needs_startup()
{
  A::initialize();
  //do the foo
}
</code></pre>
<p>So wird die Exception erst geworfen, wenn das erste mal eine Funktion aufgerufen wird, die initialize() aufruft. Alle weiteren Aufrufe von initialize() machen nichts mehr. Abgeräumt wird das Objekt wie gehabt nach Beendigung der main().<br />
PS: über Threadsafety hab ich mir im Moment keine Gedanken gemacht...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013477</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013477</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Fri, 28 Jan 2011 10:32:43 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 12:45:17 GMT]]></title><description><![CDATA[<p>Besonders der 2. Vorschlag klingt echt super. Den werde ich umsetzten können. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<blockquote>
<p>&gt; PS: über Threadsafety hab ich mir im Moment keine Gedanken gemacht...</p>
</blockquote>
<p>Das spielt zum Glück an dem Punkt keine Rolle, da die API-Funktion threadsafe ist. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Danke</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013562</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013562</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Fri, 28 Jan 2011 12:45:17 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 13:21:30 GMT]]></title><description><![CDATA[<p>Jodocus schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; PS: über Threadsafety hab ich mir im Moment keine Gedanken gemacht...</p>
</blockquote>
<p>Das spielt zum Glück an dem Punkt keine Rolle, da die API-Funktion threadsafe ist. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Danke</p>
</blockquote>
<p>Ob die API Funktion thread-safe ist oder nicht, darum geht's nicht unbedingt.<br />
Verwende einfach boost::call_once um die Init-Funktion aufzurufen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013577</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013577</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 28 Jan 2011 13:21:30 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 13:26:45 GMT]]></title><description><![CDATA[<p>Ich hab das ganze über ein Singleton gelöst. Also wenn ein Socket erzeugt wird, hole ich mir die Instanz. Diese wird dadurch erst mit dem ersten Socket erstellt und nicht immer, so wie bei dir. Diese Instanz lebt dann bis zum Programm-Schluss. Man könnte jetzt noch über einen Referenz-Zähler die cleanup-Funktion triggern, aber ich denke das wird egal sein, wann diese gerufen wird. Mir ging es nur darum diesen Mechanismus nicht selber machen zu müssen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013579</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013579</guid><dc:creator><![CDATA[psch]]></dc:creator><pubDate>Fri, 28 Jan 2011 13:26:45 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 17:05:50 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; darum geht's nicht unbedingt.</p>
</blockquote>
<p>Worum denn dann? Was kann denn schon passieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013660</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Fri, 28 Jan 2011 17:05:50 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 17:27:02 GMT]]></title><description><![CDATA[<p>In diesem einfachen Beispiel vermutlich nicht viel.<br />
&quot;Korrekt&quot; ist es IMO dennoch nicht.</p>
<p>EDIT: ich halte die Frage &quot;was kann denn schon passieren&quot; übrigens für den komplett falschen Ansatz, um nicht zu sagen: für dumm und gefährlich.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013673</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013673</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 28 Jan 2011 17:27:02 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 17:48:50 GMT]]></title><description><![CDATA[<blockquote>
<p>&gt; In diesem einfachen Beispiel vermutlich nicht viel.</p>
</blockquote>
<p>Ich behaupte mal: nichts. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<blockquote>
<p>&gt; &quot;Korrekt&quot; ist es IMO dennoch nicht.</p>
</blockquote>
<p>Wieso?</p>
<blockquote>
<p>&gt; ich halte die Frage &quot;was kann denn schon passieren&quot; übrigens für den komplett falschen Ansatz</p>
</blockquote>
<p>Ich programmiere exceptionsicher - aber hier kann einfach nichts passieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013681</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013681</guid><dc:creator><![CDATA[Jodocus]]></dc:creator><pubDate>Fri, 28 Jan 2011 17:48:50 GMT</pubDate></item><item><title><![CDATA[Reply to Exceptions im statisch aufgerufenem Konstruktor on Fri, 28 Jan 2011 22:10:40 GMT]]></title><description><![CDATA[<p>Jodocus schrieb:</p>
<blockquote>
<blockquote>
<p>&gt; In diesem einfachen Beispiel vermutlich nicht viel.</p>
</blockquote>
<p>Ich behaupte mal: nichts. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
</blockquote>
<p>Die offensichtliche Variante ist, dass es passieren könnte, dass der Konstruktor von A 2x concurrent ausgeführt wird. OK, die Funktion die im Konstruktor ausgefürht wird ist thread-safe, soll sein. Aber wer sagt dass der Compiler für die Initialisierung von statischen Variablen Coder erzeugt der thread-safe ist? Der Standard schreibt das nicht vor.</p>
<p>Je nachdem wie der Compiler die Initialisierung von statics implementiert (und auf welcher CPU das ganze läuft), könnte es auch passieren, dass A::a gar nicht initialisiert wird, wenn A::initialize gleichzeitig in zwei Threads ausgeführt wird.</p>
<p>Daher ist es nicht korrekt. So einfach ist das.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2013755</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2013755</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 28 Jan 2011 22:10:40 GMT</pubDate></item></channel></rss>