<?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[ODR: Konstanten und Inlinefunktionen im Header]]></title><description><![CDATA[<p>Dies war eigentlich als Antwort auf Tomahawk's Frage gedacht. Der <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-253556.html" rel="nofollow">Thread</a> wurde schon geschlossen. Das habe ich aber leider erst dann gemerkt, als ich die geschriebene Antwort abschicken wollte. Ich denke Tomahawks Frage war berechtigt und sein Beispiel mit Konstanten und inline-Funktionen hat mich dazu veranlasst, eine ODR-Falle zu erwähnen, welche nicht ganz uninteressant sein dürfte:</p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Wandelt der Compiler nachfolgende Definition von Konstanten automatisch in eine Zahl um, so dass ich in den Inline Functions mit den Konstanten (noch auskommentiert) statt den unlesbaren Hexzahlen arbeiten darf, ohne dass etwas langsamer wird?</p>
</blockquote>
<p>Weil der Wert von solchen Konstanten feststeht und sie nicht zur Laufzeit geändert werden dürfen, ist es einem Compiler erlaubt, die Namen der Konstanten an Stellen, wo Rvalues erwartet werden, direkt durch die Werte zu ersetzen, ohne dafür extra eine Konstante im Speicher anzulegen. Erst wenn die Adresse eines solchen Objekts benutzt wird, muss der Compiler auch Speicher für die Konstante anlegen. Diesbezüglich muss man aber etwas aufpassen:</p>
<p>Irgendeine Header-Datei:</p>
<pre><code class="language-cpp">#ifndef SOME_HEADER_INCLUDED
#define SOME_HEADER_INCLUDED

#include &lt;vector&gt;

const int dings = 31415;

inline void bums(std::vector&lt;int&gt; &amp; v) {
  v.push_back(dings);
}

#endif // SOME_HEADER_INCLUDED
</code></pre>
<p>Hier gibt es eine Verletzung der ODR (one definition rule), falls diese Headerdatei in mehreren Übersetzungseinheiten eingebunden wird. <code>dings</code> hat eine interne Bindung, <code>bums</code> aber nicht. Die ODR erlaubt die Mehrfachdefinition von Funktionstemplates und Inline-Funktionen (höchstens eine pro ÜE aber insgesamt auch mehr als eine), verlangt aber, dass die Definition dieselbe ist, wobei sich auch alle verwendeten Bezeichner auf dieselbe Entität beziehen, falls mehr als nur ihr Wert verwendet wird. In diesem Beispiel biezieht sich aber <code>dings</code> immer auf ein anderes Objekt, da jede ÜE ihr eigenes <code>dings</code> bekommt. Die <code>push_back</code> -Funktion nimmt ihren Parameter als Referenz-auf-const entgegen, was eine Adresse erfordert. Das führt dazu, dass die Definitionen von bums über versch ÜEs nicht mehr dieselben sind --&gt; Verletzung der ODR.</p>
<p>Die Variation</p>
<pre><code class="language-cpp">inline void bums(std::vector&lt;int&gt; &amp; v) {
  v.push_back(dings+0);
}
</code></pre>
<p>erzeugt stattdessen ein temporäres int-Objekt und übergibt die Adresse der push_back-Funktion. Hier wird die ODR nicht mehr verletzt.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/253563/odr-konstanten-und-inlinefunktionen-im-header</link><generator>RSS for Node</generator><lastBuildDate>Sun, 13 Sep 2026 16:48:56 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/253563.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 04 Nov 2009 09:07:29 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to ODR: Konstanten und Inlinefunktionen im Header on Wed, 04 Nov 2009 09:11:33 GMT]]></title><description><![CDATA[<p>Dies war eigentlich als Antwort auf Tomahawk's Frage gedacht. Der <a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-253556.html" rel="nofollow">Thread</a> wurde schon geschlossen. Das habe ich aber leider erst dann gemerkt, als ich die geschriebene Antwort abschicken wollte. Ich denke Tomahawks Frage war berechtigt und sein Beispiel mit Konstanten und inline-Funktionen hat mich dazu veranlasst, eine ODR-Falle zu erwähnen, welche nicht ganz uninteressant sein dürfte:</p>
<p>Tomahawk schrieb:</p>
<blockquote>
<p>Wandelt der Compiler nachfolgende Definition von Konstanten automatisch in eine Zahl um, so dass ich in den Inline Functions mit den Konstanten (noch auskommentiert) statt den unlesbaren Hexzahlen arbeiten darf, ohne dass etwas langsamer wird?</p>
</blockquote>
<p>Weil der Wert von solchen Konstanten feststeht und sie nicht zur Laufzeit geändert werden dürfen, ist es einem Compiler erlaubt, die Namen der Konstanten an Stellen, wo Rvalues erwartet werden, direkt durch die Werte zu ersetzen, ohne dafür extra eine Konstante im Speicher anzulegen. Erst wenn die Adresse eines solchen Objekts benutzt wird, muss der Compiler auch Speicher für die Konstante anlegen. Diesbezüglich muss man aber etwas aufpassen:</p>
<p>Irgendeine Header-Datei:</p>
<pre><code class="language-cpp">#ifndef SOME_HEADER_INCLUDED
#define SOME_HEADER_INCLUDED

#include &lt;vector&gt;

const int dings = 31415;

inline void bums(std::vector&lt;int&gt; &amp; v) {
  v.push_back(dings);
}

#endif // SOME_HEADER_INCLUDED
</code></pre>
<p>Hier gibt es eine Verletzung der ODR (one definition rule), falls diese Headerdatei in mehreren Übersetzungseinheiten eingebunden wird. <code>dings</code> hat eine interne Bindung, <code>bums</code> aber nicht. Die ODR erlaubt die Mehrfachdefinition von Funktionstemplates und Inline-Funktionen (höchstens eine pro ÜE aber insgesamt auch mehr als eine), verlangt aber, dass die Definition dieselbe ist, wobei sich auch alle verwendeten Bezeichner auf dieselbe Entität beziehen, falls mehr als nur ihr Wert verwendet wird. In diesem Beispiel biezieht sich aber <code>dings</code> immer auf ein anderes Objekt, da jede ÜE ihr eigenes <code>dings</code> bekommt. Die <code>push_back</code> -Funktion nimmt ihren Parameter als Referenz-auf-const entgegen, was eine Adresse erfordert. Das führt dazu, dass die Definitionen von bums über versch ÜEs nicht mehr dieselben sind --&gt; Verletzung der ODR.</p>
<p>Die Variation</p>
<pre><code class="language-cpp">inline void bums(std::vector&lt;int&gt; &amp; v) {
  v.push_back(dings+0);
}
</code></pre>
<p>erzeugt stattdessen ein temporäres int-Objekt und übergibt die Adresse der push_back-Funktion. Hier wird die ODR nicht mehr verletzt.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1803042</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1803042</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Wed, 04 Nov 2009 09:11:33 GMT</pubDate></item><item><title><![CDATA[Reply to ODR: Konstanten und Inlinefunktionen im Header on Wed, 04 Nov 2009 15:02:51 GMT]]></title><description><![CDATA[<p>Sebastian Pizer schrieb:</p>
<blockquote>
<p>Die <code>push_back</code> -Funktion nimmt ihren Parameter als Referenz-auf-const entgegen, was eine Adresse erfordert.</p>
</blockquote>
<p>Da bin ich nicht so sicher.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1803269</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1803269</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 04 Nov 2009 15:02:51 GMT</pubDate></item></channel></rss>