<?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[Macht RVO meine Übung kaputt?]]></title><description><![CDATA[<p>Hey Leute, ich wollte heute mal anfangen, mich mit RValue Referenzen zu beschäftigen und habe dieses kleine Programm geschrieben:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;utility&gt; //für std::move
#include &lt;vector&gt;
#include &lt;cstdlib&gt;
struct A
{
	std::vector&lt;int&gt; n;

	A(A&amp;&amp; a)  {  n.swap(a.n); std::cout&lt;&lt;&quot;swaped&quot;&lt;&lt;std::endl; }
	A(const A&amp;  a) : n(a.n) { std::cout&lt;&lt;&quot;kopiert&quot;&lt;&lt;std::endl; }
	A() {}
};

A f() //erstellt irgendein Objekt vom Typ A
{
	A a;
	a.n.push_back(rand());
	return a;
}

int main()
{
	A b,c;

	A a1(b); //Erwartet: normaler Konstruktor. Passt.
	A a2(std::move(c)); //Erwartet: Rvalue Construktor: Passt
	A a3(f()); //Erwartet: Rvalue Konstruktor. Passt nicht.
}
</code></pre>
<p>Ausgabe:</p>
<blockquote>
<p>kopiert<br />
swaped</p>
</blockquote>
<p>Das Erzeugen von a1 und a2 läuft so, wie ich es mir denke (über die entsprechenden Konstruktoren). Bei a3 hätte ich erwartet, dass es auch über den RValue Konstruktor initialisiert wird, allerdings wird bei mir keiner der beiden Konstruktoren benutzt. Liegt das daran, dass mein Compiler durch RVO alle Konstruktoraufrufe wegoptimiert oder daran, dass ich RValue Referenzen nicht verstanden habe?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/315774/macht-rvo-meine-übung-kaputt</link><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Jul 2026 11:57:38 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/315774.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 11 Apr 2013 14:11:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 14:11:07 GMT]]></title><description><![CDATA[<p>Hey Leute, ich wollte heute mal anfangen, mich mit RValue Referenzen zu beschäftigen und habe dieses kleine Programm geschrieben:</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;utility&gt; //für std::move
#include &lt;vector&gt;
#include &lt;cstdlib&gt;
struct A
{
	std::vector&lt;int&gt; n;

	A(A&amp;&amp; a)  {  n.swap(a.n); std::cout&lt;&lt;&quot;swaped&quot;&lt;&lt;std::endl; }
	A(const A&amp;  a) : n(a.n) { std::cout&lt;&lt;&quot;kopiert&quot;&lt;&lt;std::endl; }
	A() {}
};

A f() //erstellt irgendein Objekt vom Typ A
{
	A a;
	a.n.push_back(rand());
	return a;
}

int main()
{
	A b,c;

	A a1(b); //Erwartet: normaler Konstruktor. Passt.
	A a2(std::move(c)); //Erwartet: Rvalue Construktor: Passt
	A a3(f()); //Erwartet: Rvalue Konstruktor. Passt nicht.
}
</code></pre>
<p>Ausgabe:</p>
<blockquote>
<p>kopiert<br />
swaped</p>
</blockquote>
<p>Das Erzeugen von a1 und a2 läuft so, wie ich es mir denke (über die entsprechenden Konstruktoren). Bei a3 hätte ich erwartet, dass es auch über den RValue Konstruktor initialisiert wird, allerdings wird bei mir keiner der beiden Konstruktoren benutzt. Liegt das daran, dass mein Compiler durch RVO alle Konstruktoraufrufe wegoptimiert oder daran, dass ich RValue Referenzen nicht verstanden habe?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314770</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314770</guid><dc:creator><![CDATA[RVO?]]></dc:creator><pubDate>Thu, 11 Apr 2013 14:11:07 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 14:15:50 GMT]]></title><description><![CDATA[<p>Schon richtig so, wird RVO sein.<br />
Guck mal hier: <a href="https://ideone.com/79brIG" rel="nofollow">https://ideone.com/79brIG</a><br />
Interessant auch <a href="https://ideone.com/mdZgPP" rel="nofollow">https://ideone.com/mdZgPP</a> &lt;- Was irgendwie bitter ist, ist das überhaupt standardkonform?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314771</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314771</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Thu, 11 Apr 2013 14:15:50 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 14:14:02 GMT]]></title><description><![CDATA[<p>Diese verdammten optimierenden Compiler <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="😃"
    /> . Dann versuche ich jetzt mal, den Compiler auszutricksen. :p</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314772</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314772</guid><dc:creator><![CDATA[RVO?]]></dc:creator><pubDate>Thu, 11 Apr 2013 14:14:02 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 14:24:29 GMT]]></title><description><![CDATA[<p>Mein Compiler ist übrigens Visual Studio 2012 und Windows 7 64bit... Wäre mal echt interessant zu wissen, ob der zweite Link eine legale Ausgabe erzeugt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314776</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314776</guid><dc:creator><![CDATA[RVO?]]></dc:creator><pubDate>Thu, 11 Apr 2013 14:24:29 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 14:44:44 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>Interessant auch <a href="https://ideone.com/mdZgPP" rel="nofollow">https://ideone.com/mdZgPP</a> &lt;- Was irgendwie bitter ist, ist das überhaupt standardkonform?</p>
</blockquote>
<p>Ja, das muss so sein. Das Ergebnis des ?:-Operators ist ein lvalue, das zwar auf eine lokales Objekt verweist, es ist aber nicht der <em>Name</em> dieses Objektes, folglich fällt NRVO aus. RVO geht auch nicht, weil es eben kein temporäres Objekt ist. Macht man explizit eins daraus, gewinnt man auch nichts:</p>
<pre><code class="language-cpp">return a.n.back() &gt; 77 ? A(a) : A(b);
</code></pre>
<p>Hier greift zwar RVO, um das Move beim return zu vermeiden, aber erst einmal muss ein temporäres Objekt per Kopie erzeugt werden, und NRVO funktioniert nur mit dem return-Statement selbst... Ein explizites std::move sollte mindestens in Erwägung gezogen werden.</p>
<p><s>(Teil-)Abhilfe sollte die Verwendung von if bringen, allerdings bestenfalls für einen Zweig (es sei den der Compiler ist extrem schlau).</s> Denn er muss ja, um die Eliminierung des Moves durchführen zu können, bereits bei der Erzeugung der Objekte wissen, welches am Ende nun zurückgegeben werden wird.</p>
<p>Edit: if bringt wahrscheinlich auch nichts, weil des return-Objekt erzeugt wird, bevor irgendwelche Destruktoren ausgeführt werden, der Compiler müsste also noch berücksichtigen, das die Zerstörung in diesem Fall trivial ist.</p>
<p>Als Faustregel: NRVO ist (prizipiell) für ein bestimmtes Objekt technisch möglich, wenn sich innerhalb des potentiellen Scopes dieses Objektes kein return Statement findet, dass ein anderes als dieses Objekt zurückgibt. Diese Regel ist hier verletzt. So könnte es gehen:</p>
<pre><code class="language-cpp">A f() //erstellt irgendein Objekt vom Typ A 
{ 
    A a;
    {
        A b;
        a.n.push_back(rand()); 
        b.n.push_back(rand());
        if ( !( a.n.back() &gt; 77 ) )
            return b;
    }
    return a; 
}
</code></pre>
<p>Bei Rückgabe von b greift hier möglicherweise NRVO.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314784</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314784</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Apr 2013 14:44:44 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 15:19:12 GMT]]></title><description><![CDATA[<p>camper: Ich hatte hier kein RVO erwartet, sondern ein move. Er kopiert ja. Dass RVO nicht geht ist schon klar, das hab ich ja aktiv verhindert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314790</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314790</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Thu, 11 Apr 2013 15:19:12 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 15:37:21 GMT]]></title><description><![CDATA[<p>cooky451 schrieb:</p>
<blockquote>
<p>camper: Ich hatte hier kein RVO erwartet, sondern ein move. Er kopiert ja. Dass RVO nicht geht ist schon klar, das hab ich ja aktiv verhindert.</p>
</blockquote>
<p>Die move-Optimierung ist von ihren Voraussetzungen an RVO gekoppelt:<br />
move wird genau dann in Erwägung gezogen, wenn (N)RVO zulässig wäre bzw. nur deshalb nicht zulässig ist, weil es sich beim betreffenden Objekt um ein Funktionsargument handelt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314794</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314794</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Apr 2013 15:37:21 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 16:08:16 GMT]]></title><description><![CDATA[<p>Ah okay, das war mir nicht bewusst. Gut zu wissen, falls man sich mal wundert warum da kopiert wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314807</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314807</guid><dc:creator><![CDATA[cooky451]]></dc:creator><pubDate>Thu, 11 Apr 2013 16:08:16 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Thu, 11 Apr 2013 19:00:41 GMT]]></title><description><![CDATA[<p>Nur zum Verständnis, es würde schon reichen</p>
<pre><code class="language-cpp">return a.n.back() &gt; 77 ? move(a) : move(b);
</code></pre>
<p>zu schreiben damit wieder gemoved wird... richtig?</p>
<p>Also was schade ist ist bloss dass es nicht automatisch geht, nicht dass wir hier ein echtes Problem vorliegen hätten...?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314850</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314850</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 11 Apr 2013 19:00:41 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Fri, 12 Apr 2013 10:38:51 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>Nur zum Verständnis, es würde schon reichen</p>
<pre><code class="language-cpp">return a.n.back() &gt; 77 ? move(a) : move(b);
</code></pre>
<p>zu schreiben damit wieder gemoved wird... richtig?</p>
<p>Also was schade ist ist bloss dass es nicht automatisch geht, nicht dass wir hier ein echtes Problem vorliegen hätten...?</p>
</blockquote>
<p>Also rein intuitiv würde ich sagen ja und Ideone sagt auch:</p>
<blockquote>
<p>kopiert<br />
swaped<br />
swaped</p>
</blockquote>
<p>Was ich mich nun frage:<br />
Gibt es einen Unterschied, den man wissen müsste, zwischen</p>
<pre><code>return a.n.back() &gt; 77 ? move(a) : move(b);
</code></pre>
<p>und</p>
<pre><code>return move(a.n.back() &gt; 77 ? a : b);
</code></pre>
<p>Also die Ausgabe ist (zumindest bei Ideone - wie ich auch erwartet habe) identisch.</p>
<p>Gibts da irgendwas zu berücksichtigen?<br />
Also eigentlich wird es ja einmal (doppelt )vor dem Vergleich und einmal danach umgewandelt.</p>
<p>Gruß,<br />
XSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2314972</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314972</guid><dc:creator><![CDATA[XSpille]]></dc:creator><pubDate>Fri, 12 Apr 2013 10:38:51 GMT</pubDate></item><item><title><![CDATA[Reply to Macht RVO meine Übung kaputt? on Fri, 12 Apr 2013 11:26:05 GMT]]></title><description><![CDATA[<p>müsste eigentlich gleich sein</p>
<blockquote>
<p>5.16 Conditional operator<br />
4 If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category ...</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/2314985</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2314985</guid><dc:creator><![CDATA[dd++ 0]]></dc:creator><pubDate>Fri, 12 Apr 2013 11:26:05 GMT</pubDate></item></channel></rss>