<?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[long volatile* nach void* casten?]]></title><description><![CDATA[<p>Guten Morgen,</p>
<p>ich bin etwas erstaunt, dass mein Compiler (MSVC 10.0) folgenden Code kritisiert:</p>
<pre><code class="language-cpp">long volatile* p = static_cast&lt;long*&gt;(malloc(sizeof(long)));
free(p);
</code></pre>
<p>Die Compilerausgabe lautet:</p>
<pre><code>error C2664: 'free' : cannot convert parameter 1 from 'volatile long *' to 'void *'
</code></pre>
<p>Nun stellt sich mir die Frage nach dem &quot;Warum&quot;. Man bedenke, dass nicht der Pointer, sondern der referenzierte Long volatile ist.</p>
<p>Aus meiner Sicht gibt es, nach dem ISO-Standard, folgende implizite Konvertierungen:</p>
<pre><code class="language-cpp">void* - T*
T* - void*
0/nullptr - T*
</code></pre>
<p>wobei T für einen beliebigen Typ steht.</p>
<p>Aus welchem Grund muss ich das casten?</p>
<p>EDIT:</p>
<pre><code class="language-cpp">long volatile* p = static_cast&lt;long*&gt;(operator new(sizeof(long)));
operator delete(p);
</code></pre>
<p>Aufgrund der Verwendung von placement new möchte ich den operator new() direkt aufrufen. Ich bin mir darüber im klaren, dass damit der Konstruktor nicht aufgerufen wird <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>
<p>Das compiliert natürlich.</p>
<pre><code class="language-cpp">long volatile* p = new long;
delete p;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/272077/long-volatile-nach-void-casten</link><generator>RSS for Node</generator><lastBuildDate>Sat, 29 Aug 2026 01:11:15 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/272077.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 10 Aug 2010 07:02:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 07:06:14 GMT]]></title><description><![CDATA[<p>Guten Morgen,</p>
<p>ich bin etwas erstaunt, dass mein Compiler (MSVC 10.0) folgenden Code kritisiert:</p>
<pre><code class="language-cpp">long volatile* p = static_cast&lt;long*&gt;(malloc(sizeof(long)));
free(p);
</code></pre>
<p>Die Compilerausgabe lautet:</p>
<pre><code>error C2664: 'free' : cannot convert parameter 1 from 'volatile long *' to 'void *'
</code></pre>
<p>Nun stellt sich mir die Frage nach dem &quot;Warum&quot;. Man bedenke, dass nicht der Pointer, sondern der referenzierte Long volatile ist.</p>
<p>Aus meiner Sicht gibt es, nach dem ISO-Standard, folgende implizite Konvertierungen:</p>
<pre><code class="language-cpp">void* - T*
T* - void*
0/nullptr - T*
</code></pre>
<p>wobei T für einen beliebigen Typ steht.</p>
<p>Aus welchem Grund muss ich das casten?</p>
<p>EDIT:</p>
<pre><code class="language-cpp">long volatile* p = static_cast&lt;long*&gt;(operator new(sizeof(long)));
operator delete(p);
</code></pre>
<p>Aufgrund der Verwendung von placement new möchte ich den operator new() direkt aufrufen. Ich bin mir darüber im klaren, dass damit der Konstruktor nicht aufgerufen wird <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>
<p>Das compiliert natürlich.</p>
<pre><code class="language-cpp">long volatile* p = new long;
delete p;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1938141</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938141</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 10 Aug 2010 07:06:14 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 08:01:04 GMT]]></title><description><![CDATA[<p>Es gibt keine implizite Konvertierung <code>T volatile*</code> --&gt; <code>T*</code> . Genauso wenig wie <code>T const*</code> --&gt; <code>T*</code> . Für das erste brauchst Du nämlich einen const_cast. Vielleicht geht damit auch die zweite Konvertierung. Aber damit solltest Du hier erst gar nicht mit anfangen. Ich behaupte, dass Du volatile nicht brauchst. Das sollte eine Daumenregel sein: &quot;Wenn Du glaubst, volatile benutzen zu müssen, liegst Du wahrscheinlich falsch.&quot;</p>
<p>kk</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938157</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938157</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 10 Aug 2010 08:01:04 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 08:01:51 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Für das erste brauchst Du nämlich einen const_cast. Vielleicht geht damit auch die zweite Konvertierung.</p>
</blockquote>
<p>Upps. Habe hier &quot;erstes&quot; und &quot;zweites&quot; vertauscht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938158</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938158</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 10 Aug 2010 08:01:51 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 09:04:38 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Das sollte eine Daumenregel sein: &quot;Wenn Du glaubst, volatile benutzen zu müssen, liegst Du wahrscheinlich falsch.&quot;</p>
</blockquote>
<p>Ich greife lesend von mehreren Threads auf eine Variable zu. Ich denke schon volatile zu brauchen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938187</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938187</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 10 Aug 2010 09:04:38 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 09:21:12 GMT]]></title><description><![CDATA[<blockquote>
<p>Ich greife lesend von mehreren Threads auf eine Variable zu. Ich denke schon volatile zu brauchen.</p>
</blockquote>
<p>Wenn keiner auf die Variable schreibt, brauchst Du kein volatile und wenn einer schreibt, brauchst Du ein Lock um _alle_ Zugriffe. Volatile verhindert ja nur, dass die Variable in einem Register gehalten wird. Aber die Zugriffe darauf sind so oder so in aller Regel nicht atomar.</p>
<p>Von daher hat Krümelkacker recht:</p>
<blockquote>
<p>krümelkacker schrieb:<br />
Das sollte eine Daumenregel sein: &quot;Wenn Du glaubst, volatile benutzen zu müssen, liegst Du wahrscheinlich falsch.&quot;</p>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1938195</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938195</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 10 Aug 2010 09:21:12 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 09:27:22 GMT]]></title><description><![CDATA[<p>ogni42 schrieb:</p>
<blockquote>
<p>Wenn keiner auf die Variable schreibt, brauchst Du kein volatile und wenn einer schreibt, brauchst Du ein Lock um _alle_ Zugriffe.</p>
</blockquote>
<p>Alle können natürlich auch schreibend zugreifen. Ohne volatile bekomme ich das u.U. nicht mit. Der Schreibzugriff ist gelockt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938199</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938199</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 10 Aug 2010 09:27:22 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 09:39:41 GMT]]></title><description><![CDATA[<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>Ich greife lesend von mehreren Threads auf eine Variable zu. Ich denke schon volatile zu brauchen.</p>
</blockquote>
<p>Falsch. Dafür sind &quot;Atomics&quot; bzw &quot;Locks&quot; da. Das hat mit dem <code>volatile</code> aus C und C++ wenig zu tun.</p>
<p><a href="http://ddj.com/high-performance-computing/212701484" rel="nofollow">http://ddj.com/high-performance-computing/212701484</a><br />
<a href="http://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt" rel="nofollow">http://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt</a></p>
<p>kk</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938206</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938206</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 10 Aug 2010 09:39:41 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 09:41:40 GMT]]></title><description><![CDATA[<p>Du musst aber Schreiben <strong>und</strong> Lesen locken. Ansonsten ist der Wert beim Lesen möglicherweise undefiniert.</p>
<p>Um das möglichst &quot;verlustarm&quot; zu gestalten gibt es read/write locks.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938207</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938207</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 10 Aug 2010 09:41:40 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 10:40:39 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>Falsch.</p>
</blockquote>
<p>Nein <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="😉"
    /><br />
Es ist vom Programmablauf her nicht möglich, dass an den Stellen wo ich lese auch gleichzeitig geschrieben wird. Daher muss ich nur dafür sorgen, dass der Prozessor keine &quot;falsche Sicht&quot; auf den Inhalt der Variablen hat.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938236</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938236</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 10 Aug 2010 10:40:39 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 10:48:54 GMT]]></title><description><![CDATA[<p>Und wie kommst du zu der Annahme, dass <code>volatile</code> z.B. Cache-Effekten o.ä. entgegenwirkt? Es ist lediglich eine Anweisung an den Compiler, dass er Zugriffe auf die Variable nicht optimieren soll. Mit Threads oder CPUs oder Caches hat das aber sehr wenig zu tun.</p>
<p><a href="http://en.wikipedia.org/wiki/Volatile_variable" rel="nofollow">http://en.wikipedia.org/wiki/Volatile_variable</a> schrieb:</p>
<blockquote>
<p>The volatile keyword is basically worthless as a portable threading construct.</p>
</blockquote>
<p>Edit: verwechselst du das eventuell mit Java? Dort hat <code>volatile</code> den von dir gewünschten Effekt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938238</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938238</guid><dc:creator><![CDATA[ipsec]]></dc:creator><pubDate>Tue, 10 Aug 2010 10:48:54 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 14:12:19 GMT]]></title><description><![CDATA[<p>im neuen standars ist volatile mit einer ähnlichen bedeutung wie in java vorgesehen. (EDIT: oops, anscheinend doch nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /> /EDIT)<br />
davon abgesehen: wenn *nur* gelesen wird braucht man volatile vermutlich wirklich nicht, sondern nur eine (explizite oder implizite) barrier die nach der letzten veränderung kommt aber natürlich noch vor dem ersten lesen.</p>
<p>eine solche barrier ergibt sich normalerweise automatisch, wenn man ohne selbstgebastelte konstrukte sicherstellt, dass der programmablauf so synchronisiert ist, dass beim lesen kein anderer schreiben kann. irgendwo wartet man auf irgendwas, und im warten ist die barrier drin <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="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938248</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938248</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 10 Aug 2010 14:12:19 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 12:23:01 GMT]]></title><description><![CDATA[<p>Tut mir leid, wenn ich das falsch verstehe, aber ich möchte folgenden Effekt erzielen:</p>
<pre><code class="language-cpp">variable == 4711;
do {
	DoAwesomeStuffWithVariable();   // MT
}
while( variable == 4711 );
</code></pre>
<pre><code class="language-asm">mov eax, OFFSET variable
mov [eax], 4711

<a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/15248"><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/15248">@loop</a></a>:
;
; call StartThread etc.
;
mov eax, OFFSET variable
mov eax, [eax]
cmp eax, 4711
je  <a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/15248"><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/15248">@loop</a></a>
</code></pre>
<p>Zeile 8-9 sind entscheidend. Ich möchte nicht, dass der Compiler denkt den Wert von variable sowieso im Register zu haben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938306</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938306</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 10 Aug 2010 12:23:01 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 13:12:43 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>im neuen standars ist volatile mit einer ähnlichen bedeutung wie in java vorgesehen.</p>
</blockquote>
<p>Das halte ich für eine sehr kühne Behauptung. Kannst Du das belegen? Wozu soll denn dann bitte Kapitel 29 (&quot;Atomic operations library&quot;) des FCDs sein? Siehe auch Herb Sutter's Artikel mit dem Titel &quot;volatile vs volatile&quot;.</p>
<p>kk</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938351</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938351</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 10 Aug 2010 13:12:43 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 14:04:24 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/20434">@FrEEzE2046</a>:<br />
Woher weiss denn DoAwesomeStuffWithVariable(); dass die Threads alle fertig sind?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938376</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938376</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 10 Aug 2010 14:04:24 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 14:07:19 GMT]]></title><description><![CDATA[<p>krümelkacker schrieb:</p>
<blockquote>
<p>hustbaer schrieb:</p>
<blockquote>
<p>im neuen standars ist volatile mit einer ähnlichen bedeutung wie in java vorgesehen.</p>
</blockquote>
<p>Das halte ich für eine sehr kühne Behauptung. Kannst Du das belegen? Wozu soll denn dann bitte Kapitel 29 (&quot;Atomic operations library&quot;) des FCDs sein? Siehe auch Herb Sutter's Artikel mit dem Titel &quot;volatile vs volatile&quot;.</p>
<p>kk</p>
</blockquote>
<p>Hm.<br />
Dann hab' ich irgendwo wohl Mist aufgeschnappt.</p>
<p>Ich kann nur hoffen dass die Jungs noch ihre Meinung ändern, denn alles andere wäre IMO total doof.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938377</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938377</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 10 Aug 2010 14:07:19 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 14:26:02 GMT]]></title><description><![CDATA[<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>krümelkacker schrieb:</p>
<blockquote>
<p>Das sollte eine Daumenregel sein: &quot;Wenn Du glaubst, volatile benutzen zu müssen, liegst Du wahrscheinlich falsch.&quot;</p>
</blockquote>
<p>Ich greife lesend von mehreren Threads auf eine Variable zu. Ich denke schon volatile zu brauchen.</p>
</blockquote>
<p>Das ist leider ein Irrglaube, der sich hartnäckig hält. Insbesondere von Leuten, die IO-Ports programmiert haben.</p>
<p>Volatile darf man nicht verwechseln mit einem Cache-Write-Back. Teilweise nimmt man für solche Zwecke auch &quot;MemoryFences&quot; oder &quot;MemoryBarriers&quot;.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/ms684208%28VS.85%29.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ms684208%28VS.85%29.aspx</a></p>
<p>Insbesondere auf nicht cache-cohärenten Systemen muss man dafür Sorge tragen.</p>
<p>Ansonsten gibts ja noch conditions und signals, die man für sowas verwendet anstatt n volatile.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938379</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938379</guid><dc:creator><![CDATA[nurf]]></dc:creator><pubDate>Tue, 10 Aug 2010 14:26:02 GMT</pubDate></item><item><title><![CDATA[Reply to long volatile* nach void* casten? on Tue, 10 Aug 2010 14:38:26 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/18674">@nurf</a>:<br />
Ich würde auf anderem Weg argumentieren.</p>
<p>Woher soll/kann er wissen dass die Threads mit ihrer Arbeit fertig sind, und der Wert der Variable sich nichtmehr ändern kann?</p>
<p>Wenn er dazu Standardmechanismen wie WaitForSingleObject oder Condition-Variablen verwendet, dann beinhalten diese Mechanismen (also WaitForSingleObject bzw. die Condition-Variablen) bereits die nötigen Konstrukte (also Barriers/...).</p>
<p>Wenn er sich dazu selbst was gestrickt hat sieht die Sache natürlich anders aus. Dann müsste er genau wissen was er tun muss, um die Cache-Coherency sicherzustellen. Mit einigen Compilern (wie MSVC ab Version 8 - kann sein schon ab 7.1, weiss ich nimmer) reicht hier volatile, da diese acquire/release Semantik ala Java mit volatile verknüpfen.</p>
<p>Kurz: wer fragt ob er volatile braucht, sollte volatile nicht verwenden (und braucht es auch nicht), sondern lieber die Standardmechanismen zur Synchronisierung verwenden. Die dann auch sicherstellen dass man volatile eben nicht braucht, und auch keine expliziten Barriers o.ä.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1938386</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1938386</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 10 Aug 2010 14:38:26 GMT</pubDate></item></channel></rss>