<?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[InterlockedGet&#x2F;SetFloat Einzeiler]]></title><description><![CDATA[<p>Ist das nicht schön? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /></p>
<pre><code>float InterlockedGetFloat(float volatile* target)
{
	return *reinterpret_cast&lt;const float*&gt;(&amp;static_cast&lt;const long&amp;&gt;(InterlockedExchangeAdd(reinterpret_cast&lt;long volatile*&gt;(target), 0)));
}

void InterlockedSetFloat(float volatile* target, float value)
{
	InterlockedExchange(reinterpret_cast&lt;long volatile*&gt;(target), *reinterpret_cast&lt;long*&gt;(&amp;value));
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/324716/interlockedget-setfloat-einzeiler</link><generator>RSS for Node</generator><lastBuildDate>Mon, 13 Jul 2026 18:10:21 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/324716.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 29 Mar 2014 00:41:37 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Sat, 29 Mar 2014 00:41:37 GMT]]></title><description><![CDATA[<p>Ist das nicht schön? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /></p>
<pre><code>float InterlockedGetFloat(float volatile* target)
{
	return *reinterpret_cast&lt;const float*&gt;(&amp;static_cast&lt;const long&amp;&gt;(InterlockedExchangeAdd(reinterpret_cast&lt;long volatile*&gt;(target), 0)));
}

void InterlockedSetFloat(float volatile* target, float value)
{
	InterlockedExchange(reinterpret_cast&lt;long volatile*&gt;(target), *reinterpret_cast&lt;long*&gt;(&amp;value));
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2391696</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2391696</guid><dc:creator><![CDATA[mhat]]></dc:creator><pubDate>Sat, 29 Mar 2014 00:41:37 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Sat, 29 Mar 2014 02:24:23 GMT]]></title><description><![CDATA[<p>Nein, ist nicht schön.<br />
Und wieso überhaupt <code>InterlockedExchangeAdd</code> ? Standard für Getter wäre eher <code>InterlockedCompareExchange(&amp;p, 0, 0)</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2391700</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2391700</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 29 Mar 2014 02:24:23 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Sat, 29 Mar 2014 09:18:10 GMT]]></title><description><![CDATA[<p>Warum nicht schön? Kann das Probleme machen?<br />
Und CompareExchange hat 2 Parameter, ich denke ExchangeAdd ist performanter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2391710</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2391710</guid><dc:creator><![CDATA[mhat]]></dc:creator><pubDate>Sat, 29 Mar 2014 09:18:10 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Sat, 29 Mar 2014 18:16:48 GMT]]></title><description><![CDATA[<p>mhat schrieb:</p>
<blockquote>
<p>Warum nicht schön? Kann das Probleme machen?</p>
</blockquote>
<p>Nicht schön != kann Probleme machen</p>
<p>mhat schrieb:</p>
<blockquote>
<p>Und CompareExchange hat 2 Parameter, ich denke ExchangeAdd ist performanter.</p>
</blockquote>
<p>Denk was du willst. Wenn du es wissen willst, dann mach nen kleinen Benchmark und probier es aus.<br />
Ich finde <code>ExchangeAdd</code> in dem Zusammenhang auf jeden Fall verwirrend.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2391801</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2391801</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 29 Mar 2014 18:16:48 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Mon, 31 Mar 2014 19:21:11 GMT]]></title><description><![CDATA[<p>1. Schlechter Stil -&gt; warum pointer statt referenz.<br />
2. Durch volatile ist die Performance auch direkt wieder hin.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392065</guid><dc:creator><![CDATA[nurf]]></dc:creator><pubDate>Mon, 31 Mar 2014 19:21:11 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Mon, 31 Mar 2014 20:30:43 GMT]]></title><description><![CDATA[<blockquote>
<p>warum pointer statt referenz.</p>
</blockquote>
<p>Warum Referenz statt Zeiger?</p>
<pre><code>float InterlockedGetFloat(float volatile* target)
{
    return *reinterpret_cast&lt;const float*&gt;(&amp;static_cast&lt;const long&amp;&gt;(InterlockedExchangeAdd(reinterpret_cast&lt;long*&gt;(target), 0)));
}
</code></pre>
<p>Ist aber sowieso undefiniertes Verhalten, wegen strict aliasing.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392080</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392080</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Mon, 31 Mar 2014 20:30:43 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Mon, 31 Mar 2014 22:04:29 GMT]]></title><description><![CDATA[<p>Pointer und volatile weil InterlockedExchangeAdd auch nen volatile pointer nimmt.<br />
Brauche ich volatile also nur im Parameter?</p>
<p>UB generell oder bei MSVC nicht? <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="🙂"
    /><br />
Kannst du das mit strict aliasing genauer erklären? Und wie könnte ich es verbessern?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392090</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392090</guid><dc:creator><![CDATA[mhat]]></dc:creator><pubDate>Mon, 31 Mar 2014 22:04:29 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Tue, 01 Apr 2014 07:16:11 GMT]]></title><description><![CDATA[<blockquote>
<p>Kannst du das mit strict aliasing genauer erklären?</p>
</blockquote>
<p>§3.10/10 schrieb:</p>
<blockquote>
<p>If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:<br />
— the dynamic type of the object,<br />
— a cv-qualified version of the dynamic type of the object,<br />
— a type similar (as defined in 4.4) to the dynamic type of the object,<br />
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,<br />
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,<br />
— an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),<br />
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,<br />
— a char or unsigned char type.</p>
</blockquote>
<p>Was hier passiert, ist folgendes:</p>
<ul>
<li>
<p><code>static_cast&lt;const long&amp;&gt;(..)</code> erstellt eine Temporary vom Typ <code>long const&amp;</code> und initialisiert sie mit dem Rückgabewert von <code>InterlockedExchangeAdd</code> * -<br />
dabei wird</p>
</li>
<li>
<p>eine Temporary erstellt (vom Typ <code>long</code> ), mit dem Initializer initialisiert, und</p>
</li>
<li>
<p>die temporäre Referenz wird an diese Temporary gebunden.</p>
</li>
<li>
<p>Anschließend castest du einen Zeiger auf diese Temporary, also einen <code>long const*</code> , in <code>float const*</code> und dereferenzierst ihn.</p>
</li>
<li>
<p>Und direkt darauf folgend gibt es eine <em>lvalue-to-rvalue conversion</em>, was einen Zugriff auf das Objekt darstellt.</p>
</li>
</ul>
<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/27a1.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--right_arrow"
      title=":arrow_right:"
      alt="➡"
    /> Da du damit durch ein glvalue (genauer ein lvalue vom Typ <code>float const</code> ) auf die an die Const-Referenz gebundene Temporary vom Typ <code>long</code> zugreifst, ist es nach obigem Abschnitt UB.</p>
<p>~* Das ist nicht vom Standard gefordert, aber der sagt dass das Verhalten dem gleichen muss.~</p>
<blockquote>
<p>UB generell oder bei MSVC nicht?</p>
</blockquote>
<p>Ich kann nur sagen, dass der Standard keine Anforderungen an das Verhalten dieses Codes stellt. Bei GCC gibt es -fno-strict-aliasing, vielleicht gibt es ähnliches bei VC++.</p>
<blockquote>
<p>Und wie könnte ich es verbessern?</p>
</blockquote>
<p>Ich habe von der WinAPI und von den Funktionen keine Ahnung. Allerdings verstehe ich nicht, warum das Dereferenzieren von einem <code>float volatile*</code> nicht atomar ist? Und man dafür eine derart komplizierte Herangehensweise braucht (WinAPI)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392094</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392094</guid><dc:creator><![CDATA[Columbo]]></dc:creator><pubDate>Tue, 01 Apr 2014 07:16:11 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Mon, 31 Mar 2014 23:13:23 GMT]]></title><description><![CDATA[<p>Danke erstmal, diese Sprache ist echt ne Wissenschaft <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f62e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_with_open_mouth"
      title=":open_mouth:"
      alt="😮"
    /><br />
So ganz verstehe ich es noch nicht, außerdem muss es doch ne Möglichkeit für floats geben.<br />
So habe ich es früher gemacht, ist aber dann doch auch UB (nach std):</p>
<pre><code>float InterlockedGetFloat(float volatile* target)
{
	long value = InterlockedCompareExchange(reinterpret_cast&lt;long volatile*&gt;(target), 0, 0);
	return *reinterpret_cast&lt;float*&gt;(&amp;value);
}
</code></pre>
<p>Und wo muss man nun volatile setzen und wo nicht?</p>
<p>Das Problem ist denke ich reordering, nicht atomicity.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392096</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392096</guid><dc:creator><![CDATA[mhat]]></dc:creator><pubDate>Mon, 31 Mar 2014 23:13:23 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Tue, 01 Apr 2014 02:25:07 GMT]]></title><description><![CDATA[<p>@mhat<br />
Das verbleibende Strict Aliasing Problem behebst du indem du memcpy() verwendest.</p>
<p>Arcoth schrieb:</p>
<blockquote>
<p>Allerdings verstehe ich nicht, warum das Dereferenzieren von einem <code>float volatile*</code> nicht atomar ist? Und man dafür eine derart komplizierte Herangehensweise braucht (WinAPI)?</p>
</blockquote>
<p>Warum sollte es das sein?<br />
Der C++ Standard sagt darüber nix, und irgendwelche Windows Standards vermutlich auch nicht.<br />
Wenn dann wäre hier der x86/amd64 &quot;Standard&quot; gefragt.<br />
Ob der atomic float reads hat weiss ich nicht. Ist dann aber nicht protiertbar - also wieso überhaupt gross darüber nachdenken?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392112</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392112</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 01 Apr 2014 02:25:07 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Wed, 02 Apr 2014 19:38:50 GMT]]></title><description><![CDATA[<p>Aber in dem Fall würde memcpy doch die Interlocked-Funktionalität zunichtemachen. Ich muss die Adresse des floats direkt übergeben, und nicht mit Zwischenvariablen arbeiten, sonst macht der lock doch keinen Sinn mehr?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392431</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392431</guid><dc:creator><![CDATA[mhat]]></dc:creator><pubDate>Wed, 02 Apr 2014 19:38:50 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Wed, 02 Apr 2014 20:33:44 GMT]]></title><description><![CDATA[<p>Nö, so:</p>
<pre><code class="language-cpp">float InterlockedGetFloat(float volatile* ptr)
{ 
     static_assert(sizeof(float) == sizeof(long), &quot;float &lt;-&gt; long size mismtach&quot;);

     long lval = InterlockedCompareExchange(reinterpret_cast&lt;long volatile*&gt;(ptr), 0, 0); 

     float fval;
     memcpy(&amp;fval, &amp;lval, sizeof(float));
     return fval;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2392451</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392451</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 02 Apr 2014 20:33:44 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Wed, 02 Apr 2014 20:53:58 GMT]]></title><description><![CDATA[<p>Warum diese Asymmetrie? Sollte man memcpy() nicht auch einsetzen, um den float in einen long zu konvertieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392456</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392456</guid><dc:creator><![CDATA[symsung]]></dc:creator><pubDate>Wed, 02 Apr 2014 20:53:58 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Wed, 02 Apr 2014 21:21:04 GMT]]></title><description><![CDATA[<p>Nein, sollte man nicht.<br />
<code>InterlockedCompareExchange</code> ist atomar und ein Fence.<br />
<code>memcpy</code> ist keines von beiden.</p>
<p>Wenn du direkt <code>memcpy</code> zum lesen verwendest, kannst du die ganze Funktion auch gleich weglassen und die Aufrufe durch <code>*ptr</code> ersetzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392460</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392460</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 02 Apr 2014 21:21:04 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Wed, 02 Apr 2014 21:53:36 GMT]]></title><description><![CDATA[<p>SetFloat demnach:</p>
<pre><code>void InterlockedSetFloat(float volatile* target, float value)
{
	static_assert(sizeof(float) == sizeof(long), &quot;float &lt;-&gt; long size mismatch&quot;);

	long lval;

	memcpy(&amp;lval, &amp;value, sizeof(long));

	InterlockedExchange(reinterpret_cast&lt;long volatile*&gt;(target), lval);
}
</code></pre>
<p>Aber ich dachte, der reinterpret_cast von float* nach long* wäre UB.. oder nicht, weil da gar nicht per lvalue zugegriffen wird? Aber indirekt ja doch (in der Interlocked-Funktion dann) ?!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392466</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392466</guid><dc:creator><![CDATA[mhat]]></dc:creator><pubDate>Wed, 02 Apr 2014 21:53:36 GMT</pubDate></item><item><title><![CDATA[Reply to InterlockedGet&#x2F;SetFloat Einzeiler on Wed, 02 Apr 2014 22:38:29 GMT]]></title><description><![CDATA[<p>Ja das ist alles so ne Sache...<br />
So wirklich sauber ist es nicht, aber ich behaupte mal es wird funktionieren.<br />
Ob es laut Standard OK ist oder nicht weiss ich ehrlich gesagt nicht. So wie ich es verstehe schon, weil man ja nur den Zeiger rumcastet.</p>
<p>Der eigentliche Zugriff passiert ja dann in Interlocked(Compare)Exchange, und da das OS Funktionen sind, darf sich mMn. die C++ Implementierung nicht daran stossen was die macht.</p>
<p>Besser wäre natürlich gleich <code>std::atomic&lt;float&gt;</code> zu verwenden.<br />
Also falls dein Compiler das unterstützt, dann vergiss den ganzen Interlocked-Quargel, und nimm das!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2392467</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2392467</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Wed, 02 Apr 2014 22:38:29 GMT</pubDate></item></channel></rss>