<?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[warning: returning reference to temporary]]></title><description><![CDATA[<p>Moinsen Community,</p>
<p>ich benutze G++ 4.8 und mich macht eine Warnung etwas stutzig.</p>
<pre><code class="language-cpp">// get name
    const std::string&amp; get_name() const{
        return names.empty() == true ? std::string() : names[0]; // &lt;== Warnung
    }
</code></pre>
<p>Aber warum spuckt der überhaupt eine Warnung da raus, wenn ich doch eine konstante Referenz zurückgebe? Einfach <code>-Wreturn-local-addr</code> abschalten und mir keinen Kopf darüber machen, oder sollte ich doch lieber nur <code>std::string</code> zurückgeben?</p>
<p>Grüße.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/316033/warning-returning-reference-to-temporary</link><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Jul 2026 07:15:14 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/316033.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 19 Apr 2013 15:12:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:12:36 GMT]]></title><description><![CDATA[<p>Moinsen Community,</p>
<p>ich benutze G++ 4.8 und mich macht eine Warnung etwas stutzig.</p>
<pre><code class="language-cpp">// get name
    const std::string&amp; get_name() const{
        return names.empty() == true ? std::string() : names[0]; // &lt;== Warnung
    }
</code></pre>
<p>Aber warum spuckt der überhaupt eine Warnung da raus, wenn ich doch eine konstante Referenz zurückgebe? Einfach <code>-Wreturn-local-addr</code> abschalten und mir keinen Kopf darüber machen, oder sollte ich doch lieber nur <code>std::string</code> zurückgeben?</p>
<p>Grüße.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316820</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316820</guid><dc:creator><![CDATA[ampersand]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:12:36 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:22:23 GMT]]></title><description><![CDATA[<p>Ähm, temporäre Objekte werden nach der Abarbeitung einer Funktion nun mal zerstört. Eine Referenz auf ein zerstörtes Objekt ist nun mal nicht so sinnvoll. <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>
]]></description><link>https://www.c-plusplus.net/forum/post/2316824</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316824</guid><dc:creator><![CDATA[out]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:22:23 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:23:34 GMT]]></title><description><![CDATA[<p>Liegt daran dass du eine Referenz auf ein temporäres string-Objekt zurückgibst, das nach dem return Statement zerstört wird.</p>
<p>Mach es so:</p>
<pre><code>const std::string&amp; get_name() const
{
    static std::string empty;
    return names.empty() == true ? empy : names[0];
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2316825</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316825</guid><dc:creator><![CDATA[Ethon]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:23:34 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:25:11 GMT]]></title><description><![CDATA[<p>Ach jetzt sehe ich was du meinst, const-ref... const-ref sollte eigentlich ein temp. Objekt am Leben erhalten, hmm gute Frage hätte jetzt auch gedacht, dass das so geht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316827</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316827</guid><dc:creator><![CDATA[out]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:25:11 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:33:28 GMT]]></title><description><![CDATA[<p>out schrieb:</p>
<blockquote>
<p>hätte jetzt auch gedacht, dass das so geht?</p>
</blockquote>
<p>nö.</p>
<p>du hast da an so einen kontext gedacht:</p>
<pre><code class="language-cpp">:::

int main() {
  string const&amp; ref = string();
  // ref ist hier noch gültig
}
</code></pre>
<p>Aber in deinem Fall trifft die &quot;Lebenszeitverlängerungsregel&quot; nicht zu. Du kannst da keine große Magie erwarten. In dem von mir gezeigten Fall ist das mit dem Verlängern aus Sicht des Compilers eine sehr einfach Sache.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316829</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316829</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:33:28 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:32:27 GMT]]></title><description><![CDATA[<p>Ethon schrieb:</p>
<blockquote>
<p>Mach es so:</p>
<pre><code>const std::string&amp; get_name() const
{
    static std::string empty;
    return names.empty() == true ? empy : names[0];
}
</code></pre>
</blockquote>
<p>Nein. Wenn dann so:</p>
<pre><code>const std::string&amp; get_name() const
{
    if (names.empty) throw out_of_range(&quot;Du hast doofe Ohren.&quot;);
    return names[0];
}
</code></pre>
<p>Oder auch ganz ohne Prüfung. Wer versucht auf ein potentiell leeres Objekt zuzugreifen, der soll damit genau so auf die Schnauze fallen, wie jemand, der front() auf einem leeren vector aufruft. Ganz schlecht an dem Vorschlag, einen leeren String zurück zu geben, ist, dass es auch semantisch falsch ist. Es ist eine Lüge. Der Name ist nicht leer. Es gibt überhaupt keinen Namen! In welchem Szenario soll solch eine Lüge sinnvoll sein?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316832</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316832</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:32:27 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:40:14 GMT]]></title><description><![CDATA[<p>out schrieb:</p>
<blockquote>
<p>const-ref sollte eigentlich ein temp. Objekt am Leben erhalten</p>
</blockquote>
<p>unter bestimmten Umständen.</p>
<p>SeppJ schrieb:</p>
<blockquote>
<p>Nein. Wenn dann so:</p>
<pre><code>const std::string&amp; get_name() const
{
    if (names.empty) throw out_of_range(&quot;Du hast doofe Ohren.&quot;);
    return names[0];
}
</code></pre>
</blockquote>
<p>Kann man auch so schreiben</p>
<pre><code class="language-cpp">const std::string&amp; get_name() const
{
    return !names.empty ? names[0] : throw out_of_range(&quot;Du hast doofe Ohren.&quot;);
}
</code></pre>
<p>Finde ich übersichtlicher, das ist aber vermutlich eine Minderheitsposition.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316833</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316833</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:40:14 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:45:09 GMT]]></title><description><![CDATA[<p>Hab mal kurz nachgedacht. Eine Funktion gibt doch theoretisch immer ein temp. Objekt zurück (darum ja auch RVO)... In dem Fall ist das ja praktisch die Referenz... Und die geht nach Abarbeitung der Funktion flöten, damit geht auch das andere tmp. Objekt flöten, auf das die Referenz zeigt...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316838</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316838</guid><dc:creator><![CDATA[out]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:45:09 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 16:03:21 GMT]]></title><description><![CDATA[<p>out schrieb:</p>
<blockquote>
<p>Hab mal kurz nachgedacht. Eine Funktion gibt doch theoretisch immer ein temp. Objekt zurück (darum ja auch RVO)</p>
</blockquote>
<p>Nein. Das ist einfach falsch und hat nichts mit RVO zu tun. Eine Funktion kopiert ihren Rückgabetyp. Da kommt eventuelle RVO ins Spiel, dass die Kopie wegoptimiert wird. Aber da ist an keiner Stelle etwas temporär.</p>
<p>Hier kannst du dir vorstellen, dass der Referenzwert kopiert wird (wenn man sich Referenzen mal als verkappte Pointer denkt). Aber nicht das Objekt, auf das sich die Referenz bezieht. Das ist wie bei der Rückgabe von Pointern. Der Pointer wird kopiert, aber nicht das, auf was er zeigt.</p>
<p>edit: Camper hat's unter mir viel besser erklärt <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316840</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316840</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 19 Apr 2013 16:03:21 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 15:59:15 GMT]]></title><description><![CDATA[<p>out schrieb:</p>
<blockquote>
<p>Hab mal kurz nachgedacht. Eine Funktion gibt doch theoretisch immer ein temp. Objekt zurück (darum ja auch RVO)... In dem Fall ist das ja praktisch die Referenz... Und die geht nach Abarbeitung der Funktion flöten, damit geht auch das andere tmp. Objekt flöten, auf das die Referenz zeigt...</p>
</blockquote>
<p>Im Normalfall, wenn keine Referenz zurückgeben wird und es sich nicht um einen skalaren Typen handelt, ist der Rückgabewert ein temporäres Objekt, das zerstört wird am Ende der Auswertung des Ausdruckes, der den Funktionsaufruf enthält. Eine Referenz wiederum ist Nichts, was überhaupt irgendwie &quot;leben&quot; würde und also zerstört werden könnte. Die Lebenszeitverlängerung, wenn ein temporäres Objekt an eine Referenz gebunden wird, beruht nicht darauf, dass die Referenz lebt, sondern dass sie einen Namen hat. Namen haben Scopes und diese Scopes kann man heranziehen, um sinnvoll über veränderte Lebenszeiten zu diskutieren. Der Rückgabewert einer Funktion dagegen ist immer etwas Namenloses.<br />
Nochmal zur Erinnerung die Ausnahmefälle ohne Lebenszeitverlängerung:<br />
1. Binden eines temporären Objektes an einen Funktionsparameter - hier lebt das temporäre Objekte sowieso schon länger.<br />
2. bei Referenzrückgabe einer Funktion (s.o.)<br />
3. Binden eines temporären Objektes an ein Referenzmember in der Konstruktotinitialisierungsliste (sowieso ziemlich exotisch, Objekt lebt in diesem Fall bis zum Ende des Konstruktors, aus technischen Gründen - sonst müsste das Objekt ja während seiner gesamten Lebenszeit Bch führen, welche Member durch Temporaries erzeugt wurden).<br />
4. (C++11) Temporäries in new-Initialisierern (eine Variante von 3., die die neue Initialisierungssyntax abdeckt).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316841</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316841</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 19 Apr 2013 15:59:15 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 16:40:33 GMT]]></title><description><![CDATA[<p>SeppJ schrieb:</p>
<blockquote>
<p>Ethon schrieb:</p>
<blockquote>
<p>Mach es so:</p>
<pre><code>const std::string&amp; get_name() const
{
    static std::string empty;
    return names.empty() == true ? empy : names[0];
}
</code></pre>
</blockquote>
<p>Nein. Wenn dann so:</p>
<pre><code>const std::string&amp; get_name() const
{
    if (names.empty) throw out_of_range(&quot;Du hast doofe Ohren.&quot;);
    return names[0];
}
</code></pre>
<p>Oder auch ganz ohne Prüfung. Wer versucht auf ein potentiell leeres Objekt zuzugreifen, der soll damit genau so auf die Schnauze fallen, wie jemand, der front() auf einem leeren vector aufruft. Ganz schlecht an dem Vorschlag, einen leeren String zurück zu geben, ist, dass es auch semantisch falsch ist. Es ist eine Lüge. Der Name ist nicht leer. Es gibt überhaupt keinen Namen! In welchem Szenario soll solch eine Lüge sinnvoll sein?</p>
</blockquote>
<p>Warum sollte es nicht sinnvoll sein wenn ein Objekt keinen Namen hat? Das macht je nach Kontext sehr viel Sinn!<br />
Deswegen hier die beste Lösung:</p>
<pre><code>boost::optional&lt;const std::string&amp;&gt; get_name() const
{
    return names.empty() ? boost::none : names[0];
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2316844</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316844</guid><dc:creator><![CDATA[Ethon]]></dc:creator><pubDate>Fri, 19 Apr 2013 16:40:33 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 16:54:08 GMT]]></title><description><![CDATA[<p>Ethon schrieb:</p>
<blockquote>
<p>Warum sollte es nicht sinnvoll sein wenn ein Objekt keinen Namen hat?</p>
</blockquote>
<p>Es kann ja offensichtlich auch keinen Namen haben. Das ist nicht der Sinn meines Beitrags. Die Aussage ist: Wenn man auf den nicht vorhandenen Namen zugreift, dann sollte die Zugriffsmethode doch bitte keinen Namen erfinden! Wenn ein nicht vorhandener Name einem leeren String entsprechen soll, dann hat dies bei der Namensgebung so gesetzt zu werden.</p>
<p>Dein vorheriger Vorschlag entspräche auf eine gewisse bekannte Containerklasse übertragen:</p>
<pre><code>template&lt;typename T&gt; class vector
{
 // ...
 T &amp;operator[](size_t index) { return  (index &gt;= size) ? T() : data[index]; }
};
</code></pre>
<p>Das kommt dir hoffentlich nicht sehr sinnvoll vor. Wenn etwas nicht da ist, dann denkt man sich nicht einfach etwas aus. Das ist ein Logikfehler im Programm, wenn auf etwas nicht-vorhandenes zugegriffen wird, und sollte auch so behandelt werden. Let it crash!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316846</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316846</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Fri, 19 Apr 2013 16:54:08 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 19:53:56 GMT]]></title><description><![CDATA[<p>ampersand schrieb:</p>
<blockquote>
<p>...</p>
<pre><code class="language-cpp">// get name
    const std::string&amp; get_name() const{
        return names.empty() == true ? std::string() : names[0]; // &lt;== Warnung
    }
</code></pre>
</blockquote>
<p>Auch wenn das etwas an der Frage vorbeiführt: Der Name einer Funktion sollte immer so präzise wie möglich sagen, was sie tut. <code>name[]</code> ist ja vermutlich ein <code>vector</code> aus <em>beliebig vielen</em> Namen, von denen nur Element 0 zurückgegeben wird. Daher wäre der bessere Name: <code>get_first_name()</code> .</p>
<p>Daraus folgt, dass der aufrufende Code wissen und <em>unterscheiden</em> können sollte, ob ein solcher &quot;erster Name&quot; überhaupt existiert (empty) oder ob er existiert, aber leer ist. Diesen Unterschied muss die Funktion bereitstellen, denn sie kann nicht wissen (-&gt; sollte nicht wissen müssen!), ob es für den <em>aufrufenden Code</em> egal ist oder nicht. Denke immer so, als ob <em>nur</em> Deine Funktion als Ware verkauft wird und irgendwo in komplett anderer Umgebung laufen soll. Das heißt:<br />
Der aufrufende Code sollte selbst den Leer-Check durchführen und ggf. für Ersatz sorgen, wenn das aus der Aufgabenstellung heraus sinnvoll ist. Wenn er trotzdem versucht, sich den &quot;ersten&quot; Namen zurückgeben zu lassen, obwohl keiner da ist, schlägt - als Selbst-Versicherung Deiner Funktion - die Exception zu.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316869</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316869</guid><dc:creator><![CDATA[minastaros]]></dc:creator><pubDate>Fri, 19 Apr 2013 19:53:56 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Fri, 19 Apr 2013 19:40:59 GMT]]></title><description><![CDATA[<p>Danke für die Antworten!<br />
Dann schmeiß ich halt ne Exception in die Runde, wenn der Vektor leer ist.</p>
<p>Grüße.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316870</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316870</guid><dc:creator><![CDATA[ampersand]]></dc:creator><pubDate>Fri, 19 Apr 2013 19:40:59 GMT</pubDate></item><item><title><![CDATA[Reply to warning: returning reference to temporary on Sat, 20 Apr 2013 08:31:51 GMT]]></title><description><![CDATA[<p>Dazu fällt mir was ein:</p>
<p>Stell Dir vor, Du hast einen Spezialvertrag mit der Post, dass sie Dir jedes Mal, wenn Du hingehst, den am weitesten vorne liegenden Brief aus Deinem Postfach geben.</p>
<p>Eines Tages fangen sie an, Dir leere Briefumschläge in die Hand zu drücken, weil im Postfach eigentlich keine Briefe mehr drin sind, uns sie in ihrer Not nicht wissen, was tun, denn sie <em>müssen</em> ja Briefe liefern... (OK, sie müssen sie nur <em>zeigen</em>...) Und es hört nicht auf...</p>
<p>Da sollte mal einer sagen: &quot;He, Dein Postfach ist leer.&quot;</p>
<p>-------------<br />
edit:<br />
Wenn Du statt <code>names[0]</code> die Methode <code>at()</code> verwendest ( <code>names.at(0)</code> ), kriegst Du die Exception <code>out_of_range</code> frei Haus geliefert, wenn der Vector leer ist, Du musst den Test dann selbst nicht machen.<br />
siehe: <a href="http://www.cplusplus.com/reference/vector/vector/at/" rel="nofollow">http://www.cplusplus.com/reference/vector/vector/at/</a></p>
<p>Fairerweise sollte man noch erwähnen, dass ein anderer STL-container, <code>map</code> , beim Aufruf von <code>myMap[key]</code> selbständig ein neues Element anlegt und zurückgibt, wenn key nicht existiert. In C++11 gibt es immerhin auch die Methode <code>map::at(key)</code> , die in diesem Fall die Exception wirft. Hier kann man sich je nach Semantik die passende Funktion raussuchen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2316875</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2316875</guid><dc:creator><![CDATA[minastaros]]></dc:creator><pubDate>Sat, 20 Apr 2013 08:31:51 GMT</pubDate></item></channel></rss>