<?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[Referenz mit Standardwert?]]></title><description><![CDATA[<p>Hi.<br />
Ist folgendes mit einer Referenz möglich?</p>
<pre><code class="language-cpp">void Call(const std::string &amp;strModule, HMODULE &amp;hModule = NULL)
{
    HMODULE hTemp = NULL;
    // mach was

    if (hModule != NULL)
    {
        hModule = hTemp;
    }
}

void Test()
{
    HMODULE hModule = NULL;
    Call(&quot;bla&quot;, hModule);
    Call(&quot;blubb&quot;);
}
</code></pre>
<p>Mit Pointern geht sowas problemlos. Ich kriege ein paar Errors, dass NULL nicht zuweisbar ist. Gibt es dennoch eine Möglichkeit, das zu realisieren?</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/264518/referenz-mit-standardwert</link><generator>RSS for Node</generator><lastBuildDate>Fri, 04 Sep 2026 15:37:46 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/264518.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 08 Apr 2010 18:44:38 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 18:44:38 GMT]]></title><description><![CDATA[<p>Hi.<br />
Ist folgendes mit einer Referenz möglich?</p>
<pre><code class="language-cpp">void Call(const std::string &amp;strModule, HMODULE &amp;hModule = NULL)
{
    HMODULE hTemp = NULL;
    // mach was

    if (hModule != NULL)
    {
        hModule = hTemp;
    }
}

void Test()
{
    HMODULE hModule = NULL;
    Call(&quot;bla&quot;, hModule);
    Call(&quot;blubb&quot;);
}
</code></pre>
<p>Mit Pointern geht sowas problemlos. Ich kriege ein paar Errors, dass NULL nicht zuweisbar ist. Gibt es dennoch eine Möglichkeit, das zu realisieren?</p>
<p>Gruß</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879597</guid><dc:creator><![CDATA[theliquidwave]]></dc:creator><pubDate>Thu, 08 Apr 2010 18:44:38 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 18:47:16 GMT]]></title><description><![CDATA[<p>Das schöne an Referenzen ist ja, dass sie nie 0 sein können. (man kann natürlich, wenn man unbedingt will etwas ungültiges erreichen..)</p>
<p>Wenn du das haben willst, dann nimm halt Zeiger.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879600</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879600</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 08 Apr 2010 18:47:16 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 18:48:04 GMT]]></title><description><![CDATA[<p>Das geht, aber ist verboten.<br />
Der C++-Standard sagt: Wenn Du NULL in eine Referenz steckst, kommen Dir Dämonen aus der Nase oder so.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879601</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879601</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 08 Apr 2010 18:48:04 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 18:50:50 GMT]]></title><description><![CDATA[<p>Ungetestet:</p>
<pre><code class="language-cpp">const HMODULE nullmodule = INVALID_HANDLE_VALUE;
void Call(const std::string &amp;strModule, HMODULE &amp;hModule = nullmodule);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879605</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879605</guid><dc:creator><![CDATA[Nukularfüsiker]]></dc:creator><pubDate>Thu, 08 Apr 2010 18:50:50 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 19:03:55 GMT]]></title><description><![CDATA[<p>Könnte es nicht sein, dass der Threadersteller dies hier sucht:</p>
<pre><code class="language-cpp">void foo(HMODULE const&amp; module = 0)
{
  // ...
}
</code></pre>
<p>Nur zur Klarstellung für den Threadersteller: Dies ist keine Nullreferenz, sowas gibt es nicht. Dies ist eine Referenz auf ein konstantes Objekt nämlich einem Literal.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879616</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879616</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 08 Apr 2010 19:03:55 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 19:55:48 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9752">@Dravere</a>:<br />
Klar gibt's Nullreferenzen. Die Frage ist nur ob es laut Standard erlaubt ist welche zu erzeugen. Wobei sich da IIRC das Committee selbst nicht einig ist.<br />
Im Moment ist man in der Community allerdings übereingekommen, wenn ich das mal so formulieren darf, dass Nullreferenzen pöse sind, und man sie nicht verwendet.</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/20378">@theliquidwave</a>:<br />
Du kannst eine non-const Referenz nicht an einen Literal binden. Steht klipp und klar im Standard dass das nicht erlaubt ist. Muss eine sog. Lvalue sein, vereinfacht gesagt: ein Objekt mit Namen oder eine andere non-const Referenz.<br />
Du kannst aber z.B. folgendes machen:</p>
<pre><code class="language-cpp">HMODULE g_dummyModuleHandle;

void Call(const std::string &amp;strModule, HMODULE &amp;hModule = g_dummyModuleHandle)
{
    HMODULE hTemp = NULL;

    // mach was

    hModule = hTemp; // Test jetzt überflüssig, landet dann halt im dummy wenn der Parameter weggelassen wurde
}
</code></pre>
<p>Ist aber nicht unbedingt schön.<br />
Ich mache in so einem Fall einfach immer zwei Funktionen, und verstecke den Dummy in einer der beiden:</p>
<pre><code class="language-cpp">void Call(const std::string &amp;strModule, HMODULE &amp;hModule)
{
    HMODULE hTemp = NULL;

    // mach was

    hModule = hTemp;
}

void Call(const std::string &amp;strModule)
{
    HMODULE dummy;
    Call(strModule, dummy);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879654</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879654</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 08 Apr 2010 19:55:48 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 20:09:35 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9752">@Dravere</a>:<br />
Klar gibt's Nullreferenzen.</p>
</blockquote>
<p>Und wie soll dies gehen? Tut mir Leid, wenn ich hier was offensichtliches übersehe, habe letzte Nacht nur 4 Stunden geschlafen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
Aber eine Referenz muss doch auf ein gültiges Objekt initialisiert werden, sobald diese erstellt wird. Ich kann eine Referenz nicht auf Nichts referenzieren lassen.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879659</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879659</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Thu, 08 Apr 2010 20:09:35 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 20:11:50 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/9752">@Dravere</a>:<br />
Klar gibt's Nullreferenzen.</p>
</blockquote>
<p>Und wie soll dies gehen? Tut mir Leid, wenn ich hier was offensichtliches übersehe, habe letzte Nacht nur 4 Stunden geschlafen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
Aber eine Referenz muss doch auf ein gültiges Objekt initialisiert werden, sobald diese erstellt wird. Ich kann eine Referenz nicht auf Nichts referenzieren lassen.</p>
</blockquote>
<p>Du weiß sicherlich, daß sowas gemeint war.</p>
<pre><code class="language-cpp">int&amp; ri=*(int*)0;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879661</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879661</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 08 Apr 2010 20:11:50 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 20:18:02 GMT]]></title><description><![CDATA[<p>Microsoft C/C++ Runtime schrieb:</p>
<blockquote>
<p>Unhandled exception at 0x009113da in test.exe: 0xC0000005: Access violation reading location 0x00000006.</p>
</blockquote>
<p><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="😃"
    /></p>
<p>Edit: Auch zu müde!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879663</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879663</guid><dc:creator><![CDATA[Zeus]]></dc:creator><pubDate>Thu, 08 Apr 2010 20:18:02 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 20:43:02 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Klar gibt's Nullreferenzen. Die Frage ist nur ob es laut Standard erlaubt ist welche zu erzeugen. Wobei sich da IIRC das Committee selbst nicht einig ist.</p>
</blockquote>
<p>Denkst du gerade an einen bestimmten Punkt, wo es nicht eindeutig ist? Mir fiele nämlich keiner ein. Man könnte zwar argumentieren, dass</p>
<pre><code class="language-cpp">T&amp; ref = *(T*)0;
</code></pre>
<p>okay sei, solange nicht direkt auf <code>ref</code> zugegriffen wird (d.h. nur mit Adressoperator, <code>sizeof</code> oder so). Aber das scheint mir mehr Spekulation zu sein.</p>
<p>Der C++-Standard spricht diesbezüglich deutliche Worte:</p>
<p>§8.3.2/4 schrieb:</p>
<blockquote>
<p>A reference shall be initialized to refer to a valid object or function. [Note: in particular, <strong>a null reference cannot exist</strong> in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. [...&rsqb;&rsqb;</p>
</blockquote>
<p>Und die Dereferenzierung eines Nullzeigers ist nur in einem mir bekannten Kontext wohldefiniert, nämlich innerhalb eines <code>typeid</code> -Operators. Der Referenz bringt das nichts. Ich finde die Aussage, es gäbe keine (in C++ erlaubten) Nullreferenzen, also gar nicht so abwegig. Zumal diese keinen praktischen Nutzen haben und man sich auf nichts verlassen kann, sobald man sie einsetzt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879675</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879675</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 08 Apr 2010 20:43:02 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 20:47:57 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Und die Dereferenzierung eines Nullzeigers ist nur in einem mir bekannten Kontext wohldefiniert, nämlich innerhalb eines <code>typeid</code> -Operators.</p>
</blockquote>
<p>Das überrascht mich. Erwarten würde ich, daß, wenn typeid es kann, auch sizeof es kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879677</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879677</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 08 Apr 2010 20:47:57 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 20:56:16 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>Das überrascht mich. Erwarten würde ich, daß, wenn typeid es kann, auch sizeof es kann.</p>
</blockquote>
<p>Da der <code>sizeof</code> -Operator den übergebenen Ausdruck nicht vollständig auswertet, spielt der Wert des Zeigers keine Rolle. Es kommt also keine Dereferenzierung zum Zuge, selbst wenns so aussieht.</p>
<p>Ist natürlich Definitionssache, was nun Dereferenzierung ist. Es ist wahrscheinlich besser, nicht nur die Laufzeit zu betrachten. Solche Aktionen dürfen prinzipiell auch fehlschlagen, falls <code>ptr</code> Null ist:</p>
<pre><code class="language-cpp">&amp;*ptr
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879682</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879682</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 08 Apr 2010 20:56:16 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 21:23:13 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Klar gibt's Nullreferenzen. Die Frage ist nur ob es laut Standard erlaubt ist welche zu erzeugen. Wobei sich da IIRC das Committee selbst nicht einig ist.</p>
</blockquote>
<p>Denkst du gerade an einen bestimmten Punkt, wo es nicht eindeutig ist? Mir fiele nämlich keiner ein. Man könnte zwar argumentieren, dass</p>
<pre><code class="language-cpp">T&amp; ref = *(T*)0;
</code></pre>
<p>okay sei, solange nicht direkt auf <code>ref</code> zugegriffen wird (d.h. nur mit Adressoperator, <code>sizeof</code> oder so). Aber das scheint mir mehr Spekulation zu sein.</p>
<p>Der C++-Standard spricht diesbezüglich deutliche Worte:</p>
<p>§8.3.2/4 schrieb:</p>
<blockquote>
<p>A reference shall be initialized to refer to a valid object or function. [Note: in particular, <strong>a null reference cannot exist</strong> in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by dereferencing a null pointer, which causes undefined behavior. [...&rsqb;&rsqb;</p>
</blockquote>
<p>Und die Dereferenzierung eines Nullzeigers ist nur in einem mir bekannten Kontext wohldefiniert, nämlich innerhalb eines <code>typeid</code> -Operators. Der Referenz bringt das nichts. Ich finde die Aussage, es gäbe keine (in C++ erlaubten) Nullreferenzen, also gar nicht so abwegig. Zumal diese keinen praktischen Nutzen haben und man sich auf nichts verlassen kann, sobald man sie einsetzt.</p>
</blockquote>
<p>Irgendwer (vielleicht camper oder pumuckl?) hat hier mal was verlinkt wo im Endeffekt eine Diskussion zu finden war ob das nun erlaubt sein sollte oder nicht.<br />
Da dein Zitat ja belegt dass es im aktuellen Standard klardefinierterweise nicht OK ist, ging es da vermutlich um den kommenden Standard, und Änderungen die da gemacht werden sollen bzw. ob und wenn wie sie gemacht werden sollen.</p>
<p>Und: gibt es im aktuellen Standard denn eine Ausnahme was typeid()/sizeof() angeht? Ich meine es ist logisch dass es egal sein muss, aber steht es auch im Standard? <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>Kann auch sein dass genau das einer der Gründe war, warum vorgeschlagen wurde da etwas zu ändern. Also damit ein für allemal klar ist, dass es in sizeof/typeid OK ist. Und ich glaube mich zu erinnern, dass auch vorgeschlagen wurde das gleich so weit auszudehnen, dass es überall OK wäre. Gründe weiss ich nimmer, und ich bin auch nimmer 100% sicher.</p>
<p>Kann mich nurmehr erinnern dass ich mir gedacht habe <em>huch, dann fällt vielleicht die 'Referenzen müssen immer auf was zeigen' Sache - hoffentlich fängt die nächste Generation von C++ Programmierern nicht an das auch so zu verwenden</em>.</p>
<p>Im Prinzip gaukelt dieser Passus im Standard einem ja bereits heute eine falsche Sicherheit vor. Es steht ja nur da dass Referenzen immer mit einem gültigen Objekt *initialisiert* werden müssen. Ich kenne aber einige Programme, wo nicht sichergestellt ist, dass solche Objekte nicht gelöscht werden, bevor die Referenz gelöscht wird. Nur die Referenz wird danach halt einfach nimmer verwendet. Geben tut es sie aber noch, und sie zeigt fröhlich ins Nirvana. Ist natürlich was anderes als eine Nullreferenz, aber auch nicht ganz ohne.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879694</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879694</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 08 Apr 2010 21:23:13 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 21:31:54 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Im Prinzip gaukelt dieser Passus im Standard einem ja bereits heute eine falsche Sicherheit vor. Es steht ja nur da dass Referenzen immer mit einem gültigen Objekt *initialisiert* werden müssen. Ich kenne aber einige Programme, wo nicht sichergestellt ist, dass solche Objekte nicht gelöscht werden, bevor die Referenz gelöscht wird. Nur die Referenz wird danach halt einfach nimmer verwendet. Geben tut es sie aber noch, und sie zeigt fröhlich ins Nirvana. Ist natürlich was anderes als eine Nullreferenz, aber auch nicht ganz ohne.</p>
</blockquote>
<p>Naja. Das ist aber imo ein grober Programmierfehler. Das Problem hast du bei Zeigern genau gleich. Eine &quot;void-safe&quot; Sprache zu machen ist nicht gerade ein trivialer Task. Wird im Moment bei Eiffel dran gearbeitet und funktioniert nur teilweise.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879699</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879699</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Thu, 08 Apr 2010 21:31:54 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 21:32:50 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<pre><code class="language-cpp">&amp;*ptr
</code></pre>
</blockquote>
<p>der &amp;*it steht im alten Standard als Codebeispiel, auch wenn *it undefiniert ist, weil it==foo.end(). Man ist wohl stillschqweigend davon ausgegangen, daß ein ordentlicher Compiler das schaffen. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/1879700</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879700</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 08 Apr 2010 21:32:50 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 23:16:06 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Irgendwer (vielleicht camper oder pumuckl?) hat hier mal was verlinkt wo im Endeffekt eine Diskussion zu finden war ob das nun erlaubt sein sollte oder nicht.</p>
</blockquote>
<p>Ich finde leider weder den Thread noch den Artikel, aber weiss, welchen du meinst. Hat ihn jemand? Soweit ich mich erinnere, war das Ergebnis, dass der C++-Standard von 2003 hier nicht ganz konsequent ist. Meist spricht dieser davon, die Dereferenzierung des Nullzeigers führe zu undefiniertem Verhalten, aber er erwähnt auch Ausnahmen wie <code>typeid</code> .</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Und: gibt es im aktuellen Standard denn eine Ausnahme was typeid()/sizeof() angeht? Ich meine es ist logisch dass es egal sein muss, aber steht es auch im Standard? <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>Ja. Bei <code>typeid</code> auf Nullzeiger wird <code>std::bad_typeid</code> geworfen. Bei <code>sizeof</code> kann man aus der Nichtauswertung des Ausdrucks schliessen, dass keine Dereferenzierung zur Laufzeit erfolgen kann. Hier die betreffenden Stellen:</p>
<p>Zu typeid; §5.2.8/2 schrieb:</p>
<blockquote>
<p>If the lvalue expression is obtained by applying the unary * operator to a pointer and the pointer is a null pointer value (4.10), the typeid expression throws the bad_typeid exception (18.5.3).</p>
</blockquote>
<p>Zu sizeof; §5.3.3/1 schrieb:</p>
<blockquote>
<p>The sizeof operator yields the number of bytes in the object representation of its operand. The operand is either <strong>an expression, which is not evaluated</strong>, or a parenthesized type-id.</p>
</blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>der &amp;*it steht im alten Standard als Codebeispiel, auch wenn *it undefiniert ist, weil it==foo.end(). Man ist wohl stillschqweigend davon ausgegangen, daß ein ordentlicher Compiler das schaffen. <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>Bei Iteratoren ist es sogar noch schlimmer, da <code>&amp;*it</code> in sehr vielen Fällen etwas anderes ist als <code>it</code> , sogar einen anderen Typ hat. Da kann der Compiler viel weniger optimieren und klug sein. Steht das wirklich drin?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879749</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879749</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 08 Apr 2010 23:16:06 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 23:31:26 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Compiler viel weniger optimieren und klug sein. Steht das wirklich drin?</p>
</blockquote>
<p>20.4.4.1<br />
(Kann aus meiner pdf nicht copy&amp;pasten, ich nehme den entsprechenden von <a href="http://www.cplusplus.com/reference/std/memory/uninitialized_copy/" rel="nofollow">http://www.cplusplus.com/reference/std/memory/uninitialized_copy/</a> )</p>
<p>The behavior of this function template is equivalent to:</p>
<pre><code class="language-cpp">template&lt;class InputIterator, class OutputIterator&gt;
  OutputIterator copy ( InputIterator first, InputIterator last, OutputIterator result )
{
  for (; first!=last; ++result, ++first)
    new (static_cast&lt;void*&gt;(&amp;*result))
      typename iterator_traits&lt;ForwardIterator&gt;::value_type(*first);
  return result;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879752</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879752</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 08 Apr 2010 23:31:26 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 23:43:58 GMT]]></title><description><![CDATA[<p>Die Autoren setzen wohl voraus, dass [ <code>first</code> , <code>last</code> [ eine gültige Iterator-Range ist, also kein <code>end()</code> mittendrin. Wahrscheinlich hierauf bezogen:</p>
<p>§24.1/7 Iterator requirements schrieb:</p>
<blockquote>
<p>Most of the library’s algorithmic templates that operate on data structures have interfaces that use ranges. A range is a pair of iterators that designate the beginning and end of the computation. A range [i, i) is an empty range; in general, a range [i, j) refers to the elements in the data structure starting with the one pointed to by i and up to but not including the one pointed to by j. <strong>Range [i, j) is valid if and only if j is reachable from i. The result of the application of functions in the library to invalid ranges is undefined.</strong></p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1879756</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879756</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 08 Apr 2010 23:43:58 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 23:51:24 GMT]]></title><description><![CDATA[<p>Ja, aber darf ich mit * ein Objekt ziehen, das nicht konstruiert wurde?</p>
<pre><code class="language-cpp">string* s=new string;
delete s;
*s;//erlaubt?
&amp;*s;//erlaubt?
</code></pre>
<p>Ich denke nicht (*an meine Sig denk*).</p>
<p>Oder mitr Iteratoren</p>
<pre><code class="language-cpp">vector&lt;string&gt; v;
v.reserve(1);
*v.begin();//erlaubt?
&amp;*v.begin();//erlaubt?
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879759</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879759</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Thu, 08 Apr 2010 23:51:24 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Thu, 08 Apr 2010 23:59:56 GMT]]></title><description><![CDATA[<p>Ah, ich dachte jetzt nur gerade an <code>end()</code> . Aber vor <code>uninitialized_copy()</code> ist ja der Speicher ein Trümmerfeld.</p>
<p>Nein, du hast Recht. Ich würde auch sagen, auf Raw-Speicher darf man Iteratoren nicht dereferenzieren, auch nicht vorübergehend.</p>
<p>Was gäbe es denn für Alternativen? <code>operator-&gt;</code> gäbe einen <code>T*</code> zurück, sieht schon mal gut aus. Meinst du, sowas wäre ok?</p>
<pre><code class="language-cpp">new (static_cast&lt;void*&gt;(result.operator-&gt;())) T(...)
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879762</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879762</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 08 Apr 2010 23:59:56 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Fri, 09 Apr 2010 00:07:53 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Ah, ich dachte jetzt nur gerade an <code>end()</code> . Aber vor <code>uninitialized_copy()</code> ist ja der Speicher ein Trümmerfeld.</p>
</blockquote>
<p>Ich dachte an end() eines Arrays. Da ist ja versprochen, daß die Zeigerarithmetik noch funktioniert, ich bin sogar bisher immer davon augegangen, daß der Speicher von *end() da ist, aber halt ein Trümmerfeld. Deswegen habe ich den Fall vorhin in der end-Schublade gefunden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879764</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879764</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Fri, 09 Apr 2010 00:07:53 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Fri, 09 Apr 2010 00:13:03 GMT]]></title><description><![CDATA[<p>Um nochmal auf den ursprünglichen Fall zurückzukommen, es gibt mehrere Wege, so ein Interface zu realisieren. Am einfachsten ist wohl Überladung, etwa</p>
<pre><code class="language-cpp">namespace impl {
  void call_backend(std::string const &amp;strModule, HMODULE *hModule) {
    HMODULE hTemp = NULL;
    // mach was

    if (hModule != NULL)
    {
        *hModule = hTemp;
    } 
  }
}

void Call(std::string strModule) {
  impl::call_backend(stdModule, NULL);
}

void Call(std::string strModule, HMODULE &amp;hModule) {
  impl::call_backend(strModule, &amp;hModule);
}
</code></pre>
<p>Eine andere Möglichkeit, vor allem dann sinnvoll, wenn das ganze oft gebraucht wird, wäre eine Klassenvorlage, die die Referenz verwaltet, beispielsweise (ungetestet)</p>
<pre><code class="language-cpp">template&lt;typename T&gt;
class optional_ref {
public:
  optional_ref() : ref_(0) { }
  optional_ref(T &amp;ref) : ref_(&amp;ref) { }

  // Hier kann man natürlich auch allerlei mit Operatorüberladung
  // machen, um die Benutzung natürlicher zu gestalten.
  void set(T const &amp;val) { *ref_ = val; }
  T const &amp;get() const { return *ref; }

  bool valid() const { return ref != 0; }

private:
  T *ref_;
};

void Call(std::string strModule, optional_ref&lt;HMODULE&gt; hModule = optional_ref&lt;HMODULE&gt;()) {
  HMODULE hTemp = NULL;
  // mach was

  if (hModule.valid())
  {
    hModule.set(hTemp);
  } 
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1879767</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879767</guid><dc:creator><![CDATA[seldon]]></dc:creator><pubDate>Fri, 09 Apr 2010 00:13:03 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Fri, 09 Apr 2010 00:20:44 GMT]]></title><description><![CDATA[<p>Dein optional_ref&lt;T&gt; würde ich mit boost::optional&lt;T&amp;&gt; ersetzen. Finde aber beides nicht so toll.</p>
<p>Überladung FTW!</p>
<p>Kann man - wie ich ja bereits gezeigt habe - auch einfacher machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879773</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879773</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 09 Apr 2010 00:20:44 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Fri, 09 Apr 2010 00:23:50 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Ah, ich dachte jetzt nur gerade an <code>end()</code> . Aber vor <code>uninitialized_copy()</code> ist ja der Speicher ein Trümmerfeld.</p>
<p>Nein, du hast Recht. Ich würde auch sagen, auf Raw-Speicher darf man Iteratoren nicht dereferenzieren, auch nicht vorübergehend.</p>
<p>Was gäbe es denn für Alternativen? <code>operator-&gt;</code> gäbe einen <code>T*</code> zurück, sieht schon mal gut aus. Meinst du, sowas wäre ok?</p>
<pre><code class="language-cpp">new (static_cast&lt;void*&gt;(result.operator-&gt;())) T(...)
</code></pre>
</blockquote>
<p>LOL!<br />
Wie einfach. Ich habs damals nicht hingekriegt. Bin einfach nicht auf die Idee gekommen, den operator-&gt; aufzurufen. Mir hätte das gereicht.<br />
Ganz ok? Weiß nicht, wie ich 24.1.1 zu verstehen habe, er muß nur it-&gt;m haben, falls (*it).m geht. Und das geht, sobald der Iterator ein Template ist und Klasseninstanzen verwalten könnte. Aber naja, besser als &amp;* ist es sicherlich, denn my_vector&lt;int&gt;::iterator::operator*() könnte ja einen Proxy zurückgeben, der...<br />
Oh, vector&lt;bool&gt;<br />
Der operator-&gt; kann auch einen Proxy zurückgeben.<br />
Bin wieder verwirrt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879774</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879774</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Fri, 09 Apr 2010 00:23:50 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Fri, 09 Apr 2010 00:36:16 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>LOL!<br />
Wie einfach. Ich habs damals nicht hingekriegt. Bin einfach nicht auf die Idee gekommen, den operator-&gt; aufzurufen. Mir hätte das gereicht.</p>
</blockquote>
<p>Hab zuerst auch gedacht, man müsse wohl eine Funktion haben, die von Iteratoren den Zeiger extrahieren kann. Dann hatte ich plötzlich diesen Geistesblitz. Liegt wohl an der Uhrzeit... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>volkard schrieb:</p>
<blockquote>
<p>denn my_vector&lt;int&gt;::iterator::operator*() könnte ja einen Proxy zurückgeben, der...</p>
</blockquote>
<p>Du meinst wegen des <code>reference</code> -Typedefs? Kennst du ausser <code>vector&lt;bool&gt;</code> eine Implementierung, die nicht <code>T&amp;</code> zurückgibt (nicht, dass man es nicht dürfte, interessiert mich nur)?</p>
<p>volkard schrieb:</p>
<blockquote>
<p>Oh, vector&lt;bool&gt;<br />
Der operator-&gt; kann auch einen Proxy zurückgeben.<br />
Bin wieder verwirrt.</p>
</blockquote>
<p>Ja, <code>vector&lt;bool&gt;</code> bekämpft leider Generizität, wo er nur kann. Eigentlich sollte man den rauswerfen. Ich frage mich, wie viele Programmierer schon von dessen Speicherersparnis profitiert haben? Mit <code>std::bitset</code> und <code>boost::dynamic_bitset</code> gibt es ohnehin fähigere Klassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879777</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879777</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 09 Apr 2010 00:36:16 GMT</pubDate></item><item><title><![CDATA[Reply to Referenz mit Standardwert? on Fri, 09 Apr 2010 00:42:19 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>denn my_vector&lt;int&gt;::iterator::operator*() könnte ja einen Proxy zurückgeben, der...</p>
</blockquote>
<p>Du meinst wegen des <code>reference</code> -Typedefs? Kennst du ausser <code>vector&lt;bool&gt;</code> eine Implementierung, die nicht <code>T&amp;</code> zurückgibt (nicht, dass man es nicht dürfte, interessiert mich nur)?</p>
</blockquote>
<p>Mit so Sachen habe ich damals angefangen. Auf einem 386-er mit DOS und &quot;Dinge&quot; mußten beim Dereferenzieren automatisch aus den 4M extended memory oder gar von Platte in den Bereich unter 640k hüpfen. Deswegen denke ich recht früh an Proxies. Aber ich kenne gerade keine. Das macht ja heute alles die Hardware.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1879781</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1879781</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Fri, 09 Apr 2010 00:42:19 GMT</pubDate></item></channel></rss>