<?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[Hierarchie bei Abarbeitung von Inkrementoperation]]></title><description><![CDATA[<p>Liebes Forum,</p>
<p>ich beschäftige mich seit einiger Zeit mit C++, bin aber gerade auf etwas gestossen, das ich nicht ganz verstehe.</p>
<p>Ich habe folgendes Minimalprogramm:</p>
<pre><code class="language-cpp">include&lt;iostream&gt;
unsing namespace std;

int main()
{
  int x=2;
  cout &lt;&lt; (++x)*(++x) &lt;&lt; endl; // liefert als Ausgabe : 4*4=16
  x=2;
  cout &lt;&lt; (++x)*(++x)*(++x) &lt;&lt; endl; // liefert als Ausgabe: 4*4*5=80
}
</code></pre>
<p>Mir ist nicht verständlich, warum bei der ersten Ausgabe nicht (2+1)<em>(3+1)=12 und bei der 2ten Ausgabe nicht (2+1)</em>(3+1)*(4+1)=60 geliefert wird.<br />
Ich vermute, das hängt mit der Hierarchie der Inkrement- und Multiplikationsoperatoren zusammen. Hat jemand hierfür eine Erklärung ?<br />
Vielen Dank im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/285112/hierarchie-bei-abarbeitung-von-inkrementoperation</link><generator>RSS for Node</generator><lastBuildDate>Fri, 21 Aug 2026 09:42:32 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/285112.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 14 Apr 2011 09:40:53 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 09:40:53 GMT]]></title><description><![CDATA[<p>Liebes Forum,</p>
<p>ich beschäftige mich seit einiger Zeit mit C++, bin aber gerade auf etwas gestossen, das ich nicht ganz verstehe.</p>
<p>Ich habe folgendes Minimalprogramm:</p>
<pre><code class="language-cpp">include&lt;iostream&gt;
unsing namespace std;

int main()
{
  int x=2;
  cout &lt;&lt; (++x)*(++x) &lt;&lt; endl; // liefert als Ausgabe : 4*4=16
  x=2;
  cout &lt;&lt; (++x)*(++x)*(++x) &lt;&lt; endl; // liefert als Ausgabe: 4*4*5=80
}
</code></pre>
<p>Mir ist nicht verständlich, warum bei der ersten Ausgabe nicht (2+1)<em>(3+1)=12 und bei der 2ten Ausgabe nicht (2+1)</em>(3+1)*(4+1)=60 geliefert wird.<br />
Ich vermute, das hängt mit der Hierarchie der Inkrement- und Multiplikationsoperatoren zusammen. Hat jemand hierfür eine Erklärung ?<br />
Vielen Dank im Voraus.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049210</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049210</guid><dc:creator><![CDATA[Jochen911]]></dc:creator><pubDate>Thu, 14 Apr 2011 09:40:53 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 09:49:47 GMT]]></title><description><![CDATA[<p>Jochen911 schrieb:</p>
<blockquote>
<p>Ich vermute, das hängt mit der Hierarchie der Inkrement- und Multiplikationsoperatoren zusammen. Hat jemand hierfür eine Erklärung ?</p>
</blockquote>
<p>Es gibt keine Erklärung. Was passiert ist undefiniert.</p>
<p>Das erste Beispiel kann jede Kombination von [3|4]<em>[3|4]=[9|12|16] ausgeben, kann jede Kombination aus [3|4|5]</em>[3|4|5]*[3|4|5] sein, die Spannweite reicht von 27 bis hin zu 125.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049215</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049215</guid><dc:creator><![CDATA[unsing]]></dc:creator><pubDate>Thu, 14 Apr 2011 09:49:47 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 09:59:13 GMT]]></title><description><![CDATA[<p>Hallo unsing,</p>
<p>erstmal vielen Dank für die Antwort. Warum ist das Ergebnis undefiniert ? Es wird doch eine int Variable x mit 2 initialisiert und eine Operation mit (++x) (hier ist also ++x eindeutig der Wert 3 zugeweisen, oder ?) an den cout Ausgabestrom übergeben.<br />
Der gcc Compiler rechnet in jedem Falle die angegebenen Ergebnisse aus. Diese variieren nicht, insofern kann ich deine Antwort noch nicht ganz nachvollziehen und würde mich freuen, wenn du mit noch einen kleinen Tipp zum Verständnis geben könntest.<br />
Besten Dank im Voraus !</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049219</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049219</guid><dc:creator><![CDATA[Jochen911]]></dc:creator><pubDate>Thu, 14 Apr 2011 09:59:13 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 10:01:51 GMT]]></title><description><![CDATA[<p>es ist so, dass mehrere inkrement ausrücke - ohne eine gewisse trennung - hintereinander als undefiniert festgelegt sind. kommt halt dann auf den compiler an</p>
<p>also das hier ist undefiniert:</p>
<pre><code class="language-cpp">int x = 2;
x = ++x + --x;
x = ++x * ++x + --x;
// und alles andere darusfolgende
</code></pre>
<p>steht jedoch ein logischer operator dazwischen (also &amp;&amp; oder ||), ist es wiederum erlaubt</p>
<p>da gabs ein fachausdruck für wie das heisst, aber der fällt mir nicht mehr ein</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049221</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049221</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Thu, 14 Apr 2011 10:01:51 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 10:05:54 GMT]]></title><description><![CDATA[<p>Jochen911 schrieb:</p>
<blockquote>
<p>erstmal vielen Dank für die Antwort. Warum ist das Ergebnis undefiniert ? Es wird doch eine int Variable x mit 2 initialisiert und eine Operation mit (++x) (hier ist also ++x eindeutig der Wert 3 zugeweisen, oder ?) an den cout Ausgabestrom übergeben.</p>
</blockquote>
<p>Der C++ Standard definiert nicht wann genau die Seiteneffekte von ++ eintreten. Das einzige was sicher ist ist dass x nach dem ganzen Ausdruck um 2 inkrementiert wurde. Aber wann genau die einzelnen Inkrements passieren ist undefiniert, d.h. der Compiler kann machen was er will.</p>
<p>Jochen911 schrieb:</p>
<blockquote>
<p>Der gcc Compiler rechnet in jedem Falle die angegebenen Ergebnisse aus. Diese variieren nicht, insofern kann ich deine Antwort noch nicht ganz nachvollziehen und würde mich freuen, wenn du mit noch einen kleinen Tipp zum Verständnis geben könntest.</p>
</blockquote>
<p>Dann ist das eben was der gcc in dem Fall macht. Ein anderer Compiler macht was andres...</p>
<p>Skym0sh0 schrieb:</p>
<blockquote>
<p>da gabs ein fachausdruck für wie das heisst, aber der fällt mir nicht mehr ein</p>
</blockquote>
<p>Du meinst wohl Sequence Point.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049222</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049222</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Thu, 14 Apr 2011 10:05:54 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 10:05:09 GMT]]></title><description><![CDATA[<p>Hallo Skym0sh0,</p>
<p>vielen Dank für die Antwort !!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049223</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049223</guid><dc:creator><![CDATA[Jochen911]]></dc:creator><pubDate>Thu, 14 Apr 2011 10:05:09 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 10:06:05 GMT]]></title><description><![CDATA[<p>ich meine aber, dass ich mal irgendwo gelesen hab, dass sowas von rechts nach links ausgewertet wird...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049225</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049225</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Thu, 14 Apr 2011 10:06:05 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 10:07:37 GMT]]></title><description><![CDATA[<p>Danke auch an <em>dot</em> !</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049226</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049226</guid><dc:creator><![CDATA[Jochen911]]></dc:creator><pubDate>Thu, 14 Apr 2011 10:07:37 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 11:21:16 GMT]]></title><description><![CDATA[<p>Jochen911 schrieb:</p>
<blockquote>
<p>Warum ist das Ergebnis undefiniert ? Es wird doch eine int Variable x mit 2 initialisiert und eine Operation mit (++x) (hier ist also ++x eindeutig der Wert 3 zugeweisen, oder ?)</p>
</blockquote>
<p>nein, weil nicht definiert ist, welche der Operation zuerst vollständig(!) ausgeführt wird. Im C++-Standard ist diese Operation ausdrücklich als undefiniert spezifiziert:</p>
<p>Kapitel 5 Expressions; Absatz 4</p>
<blockquote>
<p>Between the previous and next sequence point a scalar object shall have its <strong>stored value</strong> modified at <strong>most once</strong> by the evaluation of an expression.<br />
[Example:<br />
i = v[i++]; // the behavior is <strong>unspecified</strong><br />
i = 7, i++, i++; // i becomes 9<br />
i = ++i + 1; // the behavior is <strong>unspecified</strong><br />
i = i + 1; // the value of i is incremented<br />
—end example]</p>
</blockquote>
<p>man beachte insbesondere die Zeile 'i = ++i + 1;' - natürlich muss der Wert (aber nicht der Speicher!) von i zuerst um 1 erhöht werden, bevor zusätzlich 1 addiert wird, aber es ist nicht definiert, wann der inkrementierte Wert an den Speicher von i zugewiesen wird. Vor oder nach der Zuweisung an das i durch den operator=. Also das Ergebnis darf sowohl i+1 als auch i+2 sein - beides wäre denkbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049262</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049262</guid><dc:creator><![CDATA[Werner_logoff]]></dc:creator><pubDate>Thu, 14 Apr 2011 11:21:16 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 11:53:39 GMT]]></title><description><![CDATA[<p>Werner_logoff schrieb:</p>
<blockquote>
<p>Kapitel 5 Expressions; Absatz 4</p>
<blockquote>
<p>Between the previous and next sequence point a scalar object shall have its <strong>stored value</strong> modified at <strong>most once</strong> by the evaluation of an expression.<br />
[Example:<br />
i = v[i++]; // the behavior is <strong>unspecified</strong><br />
i = 7, i++, i++; // i becomes 9<br />
i = ++i + 1; // the behavior is <strong>unspecified</strong><br />
i = i + 1; // the value of i is incremented<br />
—end example]</p>
</blockquote>
<p>man beachte insbesondere die Zeile 'i = ++i + 1;' - natürlich muss der Wert (aber nicht der Speicher!) von i zuerst um 1 erhöht werden, bevor zusätzlich 1 addiert wird, aber es ist nicht definiert, wann der inkrementierte Wert an den Speicher von i zugewiesen wird. Vor oder nach der Zuweisung an das i durch den operator=. Also das Ergebnis darf sowohl i+1 als auch i+2 sein - beides wäre denkbar.</p>
</blockquote>
<p>Nach dem ersten Satz müsste das Verhalten undefiniert sein, da i zweimal modifiziert wird. Wieso ist es nur unspezifiziert?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049275</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049275</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Thu, 14 Apr 2011 11:53:39 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 12:27:59 GMT]]></title><description><![CDATA[<p>@Jochen911<br />
Ich hoffe, dass die Frage aus reinem Interesse ist und dass du nicht vor hast, jemals etwas derartiges in deinem Code zu verwenden. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049292</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049292</guid><dc:creator><![CDATA[icarus2]]></dc:creator><pubDate>Thu, 14 Apr 2011 12:27:59 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 13:01:00 GMT]]></title><description><![CDATA[<p>Unspezifiziert heißt, das Verhalten wird durch die Implementierung definiert, muss aber nicht dokumentiert werden. Undefiniert heißt, über das Verhalten kann keine Angabe gemacht werden, also auch die Compilerhersteller wissen nicht, was passiert.</p>
<p>Im vorliegenden Fall ist die Auswertereihenfolge aber grundsätzlich durch die Implementierung festgelegt. Darauf kann man sich zwar nicht verlassen, es steht nicht in der Doku, es kann bei verschiedenen Compilern, Compilerversionen und sogar verschiedenen Ausdrücken unterschiedlich sein, aber theoretisch könnte es mir der Compilerhersteller für einen bestimmten Ausdruck in einem bestimmten Kontext sagen. Es ist also &quot;nur&quot; unspezifiziert.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049307</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049307</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Thu, 14 Apr 2011 13:01:00 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 13:16:02 GMT]]></title><description><![CDATA[<p>ipsec: Soll das eine Antwort auf meine Frage sein?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049315</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049315</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Thu, 14 Apr 2011 13:16:02 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 13:18:50 GMT]]></title><description><![CDATA[<p>Ja. Wo liest du im ersten Satz, dass es undefiniert sein sollte? Das wird zwar im Forum oft so gesagt, ist aber ungenau.</p>
<p>Edit: ach so, du beziehst dich wohl auf Werners Antwort. Ich dachte du meinst den Standard.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049319</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049319</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Thu, 14 Apr 2011 13:18:50 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 13:25:01 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Werner_logoff schrieb:</p>
<blockquote>
<p>Kapitel 5 Expressions; Absatz 4</p>
<blockquote>
<p>Between the previous and next sequence point a scalar object shall have its <strong>stored value</strong> modified at <strong>most once</strong> by the evaluation of an expression.<br />
[Example:<br />
i = v[i++]; // the behavior is <strong>unspecified</strong><br />
i = 7, i++, i++; // i becomes 9<br />
i = ++i + 1; // the behavior is <strong>unspecified</strong><br />
i = i + 1; // the value of i is incremented<br />
—end example]</p>
</blockquote>
<p>man beachte insbesondere die Zeile 'i = ++i + 1;' - natürlich muss der Wert (aber nicht der Speicher!) von i zuerst um 1 erhöht werden, bevor zusätzlich 1 addiert wird, aber es ist nicht definiert, wann der inkrementierte Wert an den Speicher von i zugewiesen wird. Vor oder nach der Zuweisung an das i durch den operator=. Also das Ergebnis darf sowohl i+1 als auch i+2 sein - beides wäre denkbar.</p>
</blockquote>
<p>Nach dem ersten Satz müsste das Verhalten undefiniert sein, da i zweimal modifiziert wird. Wieso ist es nur unspezifiziert?</p>
</blockquote>
<p>Weil das Beispiel <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#351" rel="nofollow">fehlerhaft kommentiert</a> ist, das trifft ja noch auf ein paar andere Beispiele im Standard zu, also mit Vorsicht genießen. Beispiele sind sowieso nicht normativ.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049326</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049326</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 14 Apr 2011 13:25:01 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 13:35:36 GMT]]></title><description><![CDATA[<p>Hm. Und da habe ich erst heute zufällig die Definitionen gelesen (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3290.pdf" rel="nofollow">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3290.pdf</a>):</p>
<blockquote>
<p>undefined behavior<br />
behavior for which this International Standard imposes no requirements</p>
<p>unspecified behavior<br />
behavior, for a well-formed program construct and correct data, that depends on the implementation</p>
</blockquote>
<p>Naja whatever. Im Prinzip ist es ja auch egal, in beiden Fällen sollte man es in keinem Programm haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049334</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049334</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Thu, 14 Apr 2011 13:35:36 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Thu, 14 Apr 2011 13:44:30 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Weil das Beispiel <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#351" rel="nofollow">fehlerhaft kommentiert</a> ist, das trifft ja noch auf ein paar andere Beispiele im Standard zu, also mit Vorsicht genießen.</p>
</blockquote>
<p>Danke für die Bestätigung.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2049336</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2049336</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Thu, 14 Apr 2011 13:44:30 GMT</pubDate></item><item><title><![CDATA[Reply to Hierarchie bei Abarbeitung von Inkrementoperation on Mon, 18 Apr 2011 15:26:07 GMT]]></title><description><![CDATA[<p>icarus2 schrieb:</p>
<blockquote>
<p>@Jochen911<br />
Ich hoffe, dass die Frage aus reinem Interesse ist und dass du nicht vor hast, jemals etwas derartiges in deinem Code zu verwenden. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f644.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_rolling_eyes"
      title=":rolling_eyes:"
      alt="🙄"
    /></p>
</blockquote>
<p>Hallo icarus2,</p>
<p>ja, du hast recht, die Frage war nur interessehalber (bin zufällig darauf gestossen, als ich mich mit Makros beschäftigt habe):</p>
<p>z.B. ist so etwas gefährlich :</p>
<pre><code class="language-cpp">#define QUAD(x) (x*x)
</code></pre>
<p>Nutzt man nämlich irgendwo im Source Code</p>
<pre><code class="language-cpp">QUAD(++x)
</code></pre>
<p>kommt genau die besprochene Undefiniertheit ins Spiel.</p>
<p>Nutzt man dagegen eine inline Funktionsdefinition wie folgt</p>
<pre><code class="language-cpp">inline int quad( int x) 
{
return (x*x);
}
</code></pre>
<p>tritt beim Aufruf</p>
<pre><code class="language-cpp">int x = 2;
cout &lt;&lt; quad (++x);
</code></pre>
<p><strong>keine</strong> Undefiniertheit auf.</p>
<p>Selbstverständlich würde ich so etwas nicht programmieren, war reines Interesse.<br />
Danke nochmal an alle, die sich an der Diskussion beteiligt haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2051204</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2051204</guid><dc:creator><![CDATA[Jochen911]]></dc:creator><pubDate>Mon, 18 Apr 2011 15:26:07 GMT</pubDate></item></channel></rss>