<?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[volatile]]></title><description><![CDATA[<p>Hey,</p>
<pre><code>bool abort = false;
void th_func()
{
    while (!abort)
    {
        // ...
    }
}
int main()
{
    start_thread(&amp;th_func);
    sleep(1);
    abort = true;
}
</code></pre>
<p>Könnte im oben genannten Beispiel das abort vom Compiler im Register behalten werden, sodass ohne ein volatile vor abort die while immer laufen wird (C++98)?</p>
<p>Gruß,</p>
<p>Julian</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/339317/volatile</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 05:56:48 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/339317.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 20 Aug 2016 11:06:01 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 11:06:45 GMT]]></title><description><![CDATA[<p>Hey,</p>
<pre><code>bool abort = false;
void th_func()
{
    while (!abort)
    {
        // ...
    }
}
int main()
{
    start_thread(&amp;th_func);
    sleep(1);
    abort = true;
}
</code></pre>
<p>Könnte im oben genannten Beispiel das abort vom Compiler im Register behalten werden, sodass ohne ein volatile vor abort die while immer laufen wird (C++98)?</p>
<p>Gruß,</p>
<p>Julian</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506024</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506024</guid><dc:creator><![CDATA[JulianH]]></dc:creator><pubDate>Sat, 20 Aug 2016 11:06:45 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 11:40:13 GMT]]></title><description><![CDATA[<p>In C++ 98 gibt es keine threads. Wie du den konkurrierenden Zugriff regeln musst, sagt dir die Doku zu deiner Implementierung.</p>
<p>Ab C++11 gibt es dazu std::atomic, volatile hat nichts mit Threads zu tun.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506028</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506028</guid><dc:creator><![CDATA[manni66]]></dc:creator><pubDate>Sat, 20 Aug 2016 11:40:13 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 12:46:17 GMT]]></title><description><![CDATA[<p>Dass volatile raisconditions nicht verhindern kann ist mir klar, dass war aber überhaupt nicht meine Frage - ich habe mich vielleicht auch unklar ausgedrückt.<br />
(C++98) habe ich nur geschrieben, dass nicht sowas wie: benutzt doch einfach std::atomic kommt. Und was versuchst du mir mit dem Satz, dass es keine Threads in C++98 gibt zu vermitteln?</p>
<p>Mir geht es um die while. Darf der Compiler hier abort im Register halten, oder muss er abort nach jedem Durchlauf aus dem Arbeitsspeicher holen (womit ein volatile nötig wäre).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506036</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506036</guid><dc:creator><![CDATA[JulianH_]]></dc:creator><pubDate>Sat, 20 Aug 2016 12:46:17 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 15:39:11 GMT]]></title><description><![CDATA[<p>Meines Wissens ist das <code>volatile</code> genau für solche Dinge wie deine Fragestellung da,<br />
dass der Compiler von solchen Optimierungen wie <code>abort</code> in einem Register vorzuhalten<br />
Abstand nimmt, und stattdessen Code erzeugt, mit dem <code>abort</code> bei jedem Schleifendurchlauf<br />
aus dem Speicher gelesen wird.<br />
Ein weiterer Effekt von <code>volatile</code> dürfte bei dem gezeigten Code sein, dass für <code>abort</code> keine<br />
Konstantenfaltung mehr durchgeführt wird, die jedes Vorkommen von <code>abort</code> durch ein <code>false</code><br />
ersetzt und die letzte Zuweisung ( <code>abort = true;</code> ) rauswirft, weil die Variable danach nicht mehr gelesen wird.</p>
<p>Natürlich reicht <code>volatile</code> alleine nicht aus, da beispielsweise immer noch Instruktions-Reordering durch<br />
den Compiler und/oder die CPU gemacht werden könnte. So könnte im erzeugten/tatsächlich ausgeführten<br />
Code das <code>abort = true;</code> vor das <code>sleep(1);</code> wandern, was schonmal ein Fehler wäre, da dann nicht mehr<br />
mindestens eine Sekunde gewartet wird, bevor sich der Thread beendet. <code>std::atomic</code> fügt Instruktionen und<br />
Compiler-Hinweise ein die so etwas verhindern.</p>
<p>Gruss,<br />
Finnegan</p>
<p>P.S: Noch lustiger ist das &quot;Reordering&quot; natürlich wenn das <code>abort = true;</code> VOR das <code>abort = false;</code> umsortiert wird,<br />
und auch wenn ich mir sehr unsicher bin, ob das bei diesem speziellen Beispiel tatsächlich passieren kann, macht es glaube ich<br />
deutlicher, weshalb man besser <code>std::atomic</code> verwendet (es ist leicht Code zu schreiben bei dem solche lustigen Sachen passieren).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506046</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506046</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sat, 20 Aug 2016 15:39:11 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 14:58:36 GMT]]></title><description><![CDATA[<p>JulianH_ schrieb:</p>
<blockquote>
<p>Dass volatile raisconditions nicht verhindern kann ist mir klar, dass war aber überhaupt nicht meine Frage - ich habe mich vielleicht auch unklar ausgedrückt.<br />
(C++98) habe ich nur geschrieben, dass nicht sowas wie: benutzt doch einfach std::atomic kommt. Und was versuchst du mir mit dem Satz, dass es keine Threads in C++98 gibt zu vermitteln?</p>
</blockquote>
<p>ich vermute mal, dass manni damit sagen wollte, das C++98 nicht nur keine threads kennt, sondern noch dazu kein objekt-modell, dass sich um so parallele dinge schert. d.h. es gibt keinerlei zusicherungen, welche instruktionen (in zwei threads) wann und wie (synchronisiert) auf bestimmte variablen zugreifen dürfen. deshalb reicht es auch nicht (für dein beispiel), irgendeine thread library für C++98 zu verwenden, wenn du nicht die regeln deiner implementierung (compiler, library) kennst. <code>volatile</code> diente dann dafür, dein beispiel sicher zu machen, wenn *keine* threads mit im spiel sind. aber das hat ja Finnegan schon detaillierter beschrieben.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506051</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506051</guid><dc:creator><![CDATA[dove]]></dc:creator><pubDate>Sat, 20 Aug 2016 14:58:36 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 15:40:03 GMT]]></title><description><![CDATA[<p>JulianH_ schrieb:</p>
<blockquote>
<p>Mir geht es um die while. Darf der Compiler hier abort im Register halten, oder muss er abort nach jedem Durchlauf aus dem Arbeitsspeicher holen (womit ein volatile nötig wäre).</p>
</blockquote>
<p>Der Compiler darf hier machen was er will, da das undefined Behavior ist. volatile oder nicht ändert daran nix. Die Probleme hier sind nicht nur potentielles reordering, sondern fangen schon dabei an, dass nichtmal sicher ist, dass beim Lesen des bool überhaupt ein valider bool Wert rauskommt. Benutz std::atomic.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506055</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506055</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Sat, 20 Aug 2016 15:40:03 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 15:51:48 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>Der Compiler darf hier machen was er will, da das undefined Behavior ist. volatile oder nicht ändert daran nix.</p>
</blockquote>
<p>Ja, trotz meiner vorherigen Ausführungen möchte ich mich hier anschliessen. Der Standard sagt dass data races UB sind (in diesem Fall das potentiell gleichzeitige schreiben und lesen von <code>abort</code> ).<br />
In der Theorie kann kann also wirklich alles passieren. In der Praxis wird wahrscheinlich eher so äußern wie ich es in meinem Beitrag beschrieben habe.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506058</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506058</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sat, 20 Aug 2016 15:51:48 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 16:12:31 GMT]]></title><description><![CDATA[<p>Finnegan schrieb:</p>
<blockquote>
<p>P.S: Noch lustiger ist das &quot;Reordering&quot; natürlich wenn das <code>abort = true;</code> VOR das <code>abort = false;</code> umsortiert wird</p>
</blockquote>
<p>Müssen Globale-Konstruktoren nicht immer vor der main aufgerufen werden?</p>
<p>Mir ging es im Prinzip tatsächlich nur darum, ob der Compiler Variablen welche außerhalb des aktuellen Scopes sind einfach im Register halten darf.</p>
<p>Da der Compiler hier wohl optimieren darf, muss man sich natürlich situationsabhängig Gedanken machen, wie man da Fehler am besten vermeidet.<br />
In meinem Beispiel wollte ich nur eine while die nicht unendlich lang läuft, wofür dann ja volatile ausreicht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506061</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506061</guid><dc:creator><![CDATA[JulianH]]></dc:creator><pubDate>Sat, 20 Aug 2016 16:12:31 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 16:55:41 GMT]]></title><description><![CDATA[<p>JulianH schrieb:</p>
<blockquote>
<p>Müssen Globale-Konstruktoren nicht immer vor der main aufgerufen werden?</p>
</blockquote>
<p>Ja, aber Code, wo das zum Problem werden kann ist leicht geschrieben, wenn man unachtsam ist. Nicht umsonst ist die Default-Memory-Order bei <code>std::atomic</code> -Operationen auch die stärkste (auch wenn in vielen Fällen schwächere Zusicherungen ausreichen).</p>
<p>JulianH schrieb:</p>
<blockquote>
<p>Mir ging es im Prinzip tatsächlich nur darum, ob der Compiler Variablen welche außerhalb des aktuellen Scopes sind einfach im Register halten darf.</p>
</blockquote>
<p>Dafür ist das Beispiel etwas unglücklich gewählt, da das vohandene data race alle Überlegungen bezüglich Register oder Speicher müßig macht. Allerdings fällt mir so auf die Schnelle auch kein gutes Beispiel ein bei dem lediglich das volatile ausreicht.<br />
Hardware-Programmierung, bei der z.B. ein Speicherbereich auf der Hardware in den Adressraum des Prozesses gemappt ist, ohne dass mehrere Threads im Spiel sind, bieten sicher einige Anwendungsfälle für <code>volatile</code> .<br />
Und ja, in diesem Fall werden solche Optimierungen wie Variable nur im Register mit <code>volatile</code> verhindert. Ich selbst habe <code>volatile</code> bisher nur als simplen Trick verwendet um einen Algorithmus mit hardcodierten Daten zu testen<br />
(Da kann es nämlich schonmal schnell passieren dass wenn alle Daten aus de-facto-Konstanten stammen mein Algorithmus direkt vom Compiler ausgeführt wird, und dann nur das Endergebnis im kompilierten Programm landet).</p>
<p>Ich denke es ist zwar gut zu wissen, was <code>volatile</code> macht, aber dann sollte man es erstmal vergessen, besonders wenn es lediglich um Thread-Synchronisation geht. Wenn man dann tatsächlich mal irgendwelchen Hardware-Kram macht,<br />
und/oder andere Fälle hat wo es sinnvoll einzusetzen ist kann man sich gerne wieder dran erinnern, dass es <code>volatile</code> gibt.</p>
<p>Finnegan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506063</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506063</guid><dc:creator><![CDATA[Finnegan]]></dc:creator><pubDate>Sat, 20 Aug 2016 16:55:41 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 17:10:36 GMT]]></title><description><![CDATA[<p>Ich habe ein Beispiel wo <code>volatile</code> unabdingbar ist (allerdings ohne Threads):</p>
<pre><code>#include &lt;csignal&gt;

static std::sig_atomic_t volatile running = 1;

static void handler(int)
{
    running = 0;
}

int main()
{
    std::signal(SIGTERM, &amp;handler);
    std::signal(SIGINT, &amp;handler);

    while (running)
    {
        // Tu was
    }
}
</code></pre>
<p>Unter verschiedenen Compilern/Stdlibs bekam ich hier damals ohne <code>volatile</code> manchmal eine Endlosschleife.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506065</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506065</guid><dc:creator><![CDATA[Biolunar]]></dc:creator><pubDate>Sat, 20 Aug 2016 17:10:36 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 17:45:27 GMT]]></title><description><![CDATA[<p>Biolunar schrieb:</p>
<blockquote>
<p>Ich habe ein Beispiel wo <code>volatile</code> unabdingbar ist (allerdings ohne Threads):</p>
<p>Unter verschiedenen Compilern/Stdlibs bekam ich hier damals ohne <code>volatile</code> manchmal eine Endlosschleife.</p>
</blockquote>
<p>Zurecht, denn der Standard verlangt schon immer volatile für diesen speziellen Zweck.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506067</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506067</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Sat, 20 Aug 2016 17:45:27 GMT</pubDate></item><item><title><![CDATA[Reply to volatile on Sat, 20 Aug 2016 18:07:54 GMT]]></title><description><![CDATA[<p>Was genau bezweckt denn eigentlich, dass <code>running</code> 1 bleibt, trotz Signal Handler?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2506068</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2506068</guid><dc:creator><![CDATA[dumpfundstumpf]]></dc:creator><pubDate>Sat, 20 Aug 2016 18:07:54 GMT</pubDate></item></channel></rss>