<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.sarg.dev/index.php?action=history&amp;feed=atom&amp;title=Volatile_%28computer_programming%29</id>
	<title>Volatile (computer programming) - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.sarg.dev/index.php?action=history&amp;feed=atom&amp;title=Volatile_%28computer_programming%29"/>
	<link rel="alternate" type="text/html" href="https://wiki.sarg.dev/index.php?title=Volatile_(computer_programming)&amp;action=history"/>
	<updated>2026-06-24T18:42:03Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://wiki.sarg.dev/index.php?title=Volatile_(computer_programming)&amp;diff=562053&amp;oldid=prev</id>
		<title>2A02:A447:765F:0:0:0:0:169B: removed &quot;you&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.sarg.dev/index.php?title=Volatile_(computer_programming)&amp;diff=562053&amp;oldid=prev"/>
		<updated>2025-10-25T08:58:58Z</updated>

		<summary type="html">&lt;p&gt;removed &amp;quot;you&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Short description|Keyword used in some programming languages to tag variables}}&lt;br /&gt;
{{Lowercase title}}&lt;br /&gt;
In [[computer programming]], a [[Variable (computer science)|variable]] is said to be &amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039;volatile&amp;#039;&amp;#039;&amp;#039;&amp;#039;&amp;#039; if its [[Value (computer science)|value]] can be read or modified asynchronously by something other than the current [[thread (computing)|thread of execution]]. &lt;br /&gt;
The value of a &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; variable may spontaneously change for reasons such as:&lt;br /&gt;
sharing values with other threads; &lt;br /&gt;
sharing values with asynchronous [[signal handler]]s;&lt;br /&gt;
accessing hardware devices via [[memory-mapped I/O]] (where messages from [[peripheral device]]s can be received and sent by reading from and writing to memory).&lt;br /&gt;
Support for these use cases varies considerably among the programming languages that have the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword.&lt;br /&gt;
Volatility can have implications regarding function [[calling convention]]s and how variables are stored, accessed and cached.&lt;br /&gt;
&lt;br /&gt;
==In C and C++==&lt;br /&gt;
&lt;br /&gt;
In C and C++, &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; is a [[type qualifier]], like &amp;lt;code&amp;gt;[[const (computer programming)|const]]&amp;lt;/code&amp;gt;, and is a part of a [[data type|type]] (e.g. the type of a variable or field). &lt;br /&gt;
&lt;br /&gt;
The behavior of the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword in C and C++ is sometimes given in terms of suppressing optimizations of an [[optimizing compiler]]: 1- don&amp;#039;t remove existing &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes, 2- don&amp;#039;t add new &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes, and 3- don&amp;#039;t reorder &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes. However, this definition is only an approximation for the benefit of new learners, and this approximate definition should not be relied upon to write real production code.&lt;br /&gt;
&lt;br /&gt;
In C, and consequently C++, the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword was intended to:&amp;lt;ref name=&amp;quot;auto&amp;quot;&amp;gt;{{cite web |title=Publication on C++ standards committee|url= http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
*Allow access to [[memory-mapped I/O]] devices.&lt;br /&gt;
*Allow preserving values across a &amp;lt;code&amp;gt;[[setjmp|longjmp]]&amp;lt;/code&amp;gt;.&lt;br /&gt;
*Allow sharing values between signal handlers and the rest of the program in &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;sig_atomic_t&amp;lt;/code&amp;gt; objects.&lt;br /&gt;
&lt;br /&gt;
The C and C++ standards allow writing portable code that shares values across a &amp;lt;code&amp;gt;[[setjmp|longjmp]]&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; objects, and the standards allow writing portable code that shares values between signal handlers and the rest of the code in &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; &amp;lt;code&amp;gt;sig_atomic_t&amp;lt;/code&amp;gt; objects. Any other use of &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword in C and C++ is inherently non-portable or incorrect. In particular, writing code with the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword for [[memory-mapped I/O]] devices is inherently non-portable and always requires deep knowledge of the specific target C/C++ implementation and platform.   &lt;br /&gt;
&lt;br /&gt;
=== Multi-threading ===&lt;br /&gt;
It is a common misconception that the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword is useful in portable [[thread (computing)|multi-threading]] code in C and C++. The &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword in C and C++ has &amp;#039;&amp;#039;never&amp;#039;&amp;#039; functioned as a useful, portable tool for &amp;#039;&amp;#039;any&amp;#039;&amp;#039; multi-threading scenario.&amp;lt;ref&amp;gt;{{cite web |date=21 September 2021 |title=Volatile Keyword In Visual C++ |url=http://msdn2.microsoft.com/en-us/library/12a04hfd.aspx |work=Microsoft MSDN}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |title=Linux Kernel Documentation – Why the &amp;quot;volatile&amp;quot; type class should not be used |url=https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html |work=kernel.org}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |author1=Scott Meyers |author2=Andrei Alexandrescu |year=2004 |title=C++ and the Perils of Double-Checked Locking |url=http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf |work=DDJ}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |author1=Jeremy Andrews |year=2007 |title=Linux: Volatile Superstition |url=http://kerneltrap.org/Linux/Volatile_Superstition |archive-url=https://web.archive.org/web/20100620121940/http://kerneltrap.org/Linux/Volatile_Superstition |archive-date=2010-06-20 |access-date=Jan 9, 2011 |publisher=kerneltrap.org}}&amp;lt;/ref&amp;gt; Unlike the [[Java (programming language)|Java]] and [[C Sharp (programming language)|C#]] programming languages, operations on &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; variables in C and C++ are not [[atomic operation|atomic]], and operations on &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; variables do not have sufficient [[memory ordering]] guarantees (i.e. [[memory barrier|memory barriers]]). Most C and C++ compilers, linkers, and runtimes simply do not provide the necessary memory ordering guarantees to make the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword useful for &amp;#039;&amp;#039;any&amp;#039;&amp;#039; multi-threading scenario. Before the C11 and [[C++11]] standards, programmers were forced to rely on guarantees from the individual implementations and platforms (e.g. POSIX and WIN32) to write [[thread (computing)|multi-threading]] code. With the modern C11 and C++11 standards, programmers can write portable [[thread (computing)|multi-threading]] code using new portable constructs such as the &amp;lt;code&amp;gt;std::atomic&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt; templates.&amp;lt;ref&amp;gt;{{cite web |title=volatile (C++) |url=https://msdn.microsoft.com/en-us/library/12a04hfd.aspx |work=Microsoft MSDN|date=21 September 2021 }}&amp;lt;/ref&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
===Example of memory-mapped I/O in C===&lt;br /&gt;
In this example, the code sets the value stored in &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;. It then starts to [[polling (computer science)|poll]] that value repeatedly until it changes to &amp;lt;code&amp;gt;255&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static int foo;&lt;br /&gt;
&lt;br /&gt;
void bar(void) {&lt;br /&gt;
    foo = 0;&lt;br /&gt;
&lt;br /&gt;
    while (foo != 255) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An [[optimizing compiler]] will notice that no other code can possibly change the value stored in &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;, and will assume that it will remain equal to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; at all times. The compiler will therefore replace the function body with an [[infinite loop]] similar to this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void bar_optimized(void) {&lt;br /&gt;
    foo = 0;&lt;br /&gt;
&lt;br /&gt;
    while (true) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, the programmer may make &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; refer to another element of the computer system such as a [[hardware register]] of a device connected to the [[CPU]] which may change the value of &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; while this code is running. (This example does not include the details on how to make &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; refer to a hardware register of a device connected to the CPU.) Without the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword, an [[optimizing compiler]] will likely convert the code from the first sample with the read in the loop to the second sample without the read in the loop as part of the common [[Loop-invariant code motion|loop-invariant code-motion optimization]], and thus the code will likely never notice the change that it is waiting for.&lt;br /&gt;
&lt;br /&gt;
To prevent the compiler from doing this optimization, the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword can be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
static volatile int foo;&lt;br /&gt;
&lt;br /&gt;
void bar(void) {&lt;br /&gt;
    foo = 0;&lt;br /&gt;
&lt;br /&gt;
    while (foo != 255) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword prevents the compiler from moving the read out of the loop, and thus the code will notice the expected change to the variable &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Optimization comparison in C===&lt;br /&gt;
The following C programs, and accompanying assembler language excerpts, demonstrate how the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword affects the compiler&amp;#039;s output. The compiler in this case was [[GNU Compiler Collection|GCC]].&lt;br /&gt;
&lt;br /&gt;
While observing the assembly code, it is clearly visible that the code generated with &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; objects is more verbose, making it longer so the nature of &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; objects can be fulfilled. The &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword prevents the compiler from performing optimization on code involving volatile objects, thus ensuring that each volatile variable assignment and read has a corresponding memory access. Without the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword, the compiler knows a variable does not need to be reread from memory at each use, because there should not be any writes to its memory location from any other thread or process.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable collapsible collapsed&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align: center&amp;quot; colspan=2 | Assembly comparison&lt;br /&gt;
|-&lt;br /&gt;
!Without &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword||With &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    // These variables will never be created on stack&lt;br /&gt;
    int a = 10;&lt;br /&gt;
    int b = 100;&lt;br /&gt;
    int c = 0;&lt;br /&gt;
    int d = 0;&lt;br /&gt;
&lt;br /&gt;
    /* &lt;br /&gt;
    &amp;quot;printf&amp;quot; will be called with arguments &amp;quot;%d&amp;quot; and&lt;br /&gt;
    110 (the compiler computes the sum of a+b),&lt;br /&gt;
    hence no overhead of performing addition at&lt;br /&gt;
    run-time &lt;br /&gt;
    */&lt;br /&gt;
    printf(&amp;quot;%d&amp;quot;, a + b);&lt;br /&gt;
&lt;br /&gt;
    /* &lt;br /&gt;
    This code will be removed via optimization, but&lt;br /&gt;
    the impact of &amp;#039;c&amp;#039; and &amp;#039;d&amp;#039; becoming 100 can be&lt;br /&gt;
    seen while calling &amp;quot;printf&amp;quot; &lt;br /&gt;
    */&lt;br /&gt;
    a = b;&lt;br /&gt;
    c = b;&lt;br /&gt;
    d = b;&lt;br /&gt;
&lt;br /&gt;
    /* &lt;br /&gt;
    Compiler will generate code where printf is&lt;br /&gt;
    called with arguments &amp;quot;%d&amp;quot; and 200 &lt;br /&gt;
    */&lt;br /&gt;
    printf(&amp;quot;%d&amp;quot;, c + d);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
    volatile int a = 10; &lt;br /&gt;
    volatile int b = 100;&lt;br /&gt;
    volatile int c = 0;&lt;br /&gt;
    volatile int d = 0;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;%d&amp;quot;, a + b);&lt;br /&gt;
&lt;br /&gt;
    a = b;&lt;br /&gt;
    c = b;&lt;br /&gt;
    d = b;&lt;br /&gt;
&lt;br /&gt;
    printf(&amp;quot;%d&amp;quot;, c + d);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
! {{Mono|gcc -S -O3 -masm{{=}}intel noVolatileVar.c -o without.s}}&lt;br /&gt;
! {{Mono|gcc -S -O3 -masm{{=}}intel VolatileVar.c -o with.s}}&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
 .file   &amp;quot;noVolatileVar.c&amp;quot;&lt;br /&gt;
 .intel_syntax noprefix&lt;br /&gt;
 .section .rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
 .string &amp;quot;%d&amp;quot;&lt;br /&gt;
 .section .text.startup,&amp;quot;ax&amp;quot;,@progbits&lt;br /&gt;
 .p2align 4,,15&lt;br /&gt;
 .globl  main&lt;br /&gt;
 .type   main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB11:&lt;br /&gt;
 .cfi_startproc&lt;br /&gt;
 sub     rsp, 8&lt;br /&gt;
 .cfi_def_cfa_offset 16&lt;br /&gt;
 mov     esi, 110&lt;br /&gt;
 mov     edi, OFFSET FLAT:.LC0&lt;br /&gt;
 xor     eax, eax&lt;br /&gt;
 call    printf&lt;br /&gt;
 mov     esi, 200&lt;br /&gt;
 mov     edi, OFFSET FLAT:.LC0&lt;br /&gt;
 xor     eax, eax&lt;br /&gt;
 call    printf&lt;br /&gt;
 xor     eax, eax&lt;br /&gt;
 add     rsp, 8&lt;br /&gt;
 .cfi_def_cfa_offset 8&lt;br /&gt;
 ret&lt;br /&gt;
 .cfi_endproc&lt;br /&gt;
.LFE11:&lt;br /&gt;
 .size   main, .-main&lt;br /&gt;
 .ident  &amp;quot;GCC: (GNU) 4.8.2&amp;quot;&lt;br /&gt;
 .section .note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
 .file   &amp;quot;VolatileVar.c&amp;quot;&lt;br /&gt;
 .intel_syntax noprefix&lt;br /&gt;
 .section .rodata.str1.1,&amp;quot;aMS&amp;quot;,@progbits,1&lt;br /&gt;
.LC0:&lt;br /&gt;
 .string &amp;quot;%d&amp;quot;&lt;br /&gt;
 .section .text.startup,&amp;quot;ax&amp;quot;,@progbits&lt;br /&gt;
 .p2align 4,,15&lt;br /&gt;
 .globl  main&lt;br /&gt;
 .type   main, @function&lt;br /&gt;
main:&lt;br /&gt;
.LFB11:&lt;br /&gt;
 .cfi_startproc&lt;br /&gt;
 sub     rsp, 24&lt;br /&gt;
 .cfi_def_cfa_offset 32&lt;br /&gt;
 mov     edi, OFFSET FLAT:.LC0&lt;br /&gt;
 mov     DWORD PTR [rsp], 10&lt;br /&gt;
 mov     DWORD PTR [rsp+4], 100&lt;br /&gt;
 mov     DWORD PTR [rsp+8], 0&lt;br /&gt;
 mov     DWORD PTR [rsp+12], 0&lt;br /&gt;
 mov     esi, DWORD PTR [rsp]&lt;br /&gt;
 mov     eax, DWORD PTR [rsp+4]&lt;br /&gt;
 add     esi, eax&lt;br /&gt;
 xor     eax, eax&lt;br /&gt;
 call    printf&lt;br /&gt;
 mov     eax, DWORD PTR [rsp+4]&lt;br /&gt;
 mov     edi, OFFSET FLAT:.LC0&lt;br /&gt;
 mov     DWORD PTR [rsp], eax&lt;br /&gt;
 mov     eax, DWORD PTR [rsp+4]&lt;br /&gt;
 mov     DWORD PTR [rsp+8], eax&lt;br /&gt;
 mov     eax, DWORD PTR [rsp+4]&lt;br /&gt;
 mov     DWORD PTR [rsp+12], eax&lt;br /&gt;
 mov     esi, DWORD PTR [rsp+8]&lt;br /&gt;
 mov     eax, DWORD PTR [rsp+12]&lt;br /&gt;
 add     esi, eax&lt;br /&gt;
 xor     eax, eax&lt;br /&gt;
 call    printf&lt;br /&gt;
 xor     eax, eax&lt;br /&gt;
 add     rsp, 24&lt;br /&gt;
 .cfi_def_cfa_offset 8&lt;br /&gt;
 ret&lt;br /&gt;
 .cfi_endproc&lt;br /&gt;
.LFE11:&lt;br /&gt;
 .size   main, .-main&lt;br /&gt;
 .ident  &amp;quot;GCC: (GNU) 4.8.2&amp;quot;&lt;br /&gt;
 .section .note.GNU-stack,&amp;quot;&amp;quot;,@progbits&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Standards defects ===&lt;br /&gt;
While intended by both C and C++, the current C standard fails to express that the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; semantics refer to the lvalue, not the referenced object. The respective defect report &amp;#039;&amp;#039;DR 476&amp;#039;&amp;#039; (to C11) is still under review with [[C17 (C standard revision)|C17]].&amp;lt;ref&amp;gt;[http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2244.htm &amp;#039;&amp;#039;Clarification Request Summary for C11.&amp;#039;&amp;#039;] Version 1.13, October 2017.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Compiler defects ===&lt;br /&gt;
Unlike other language features of C and C++, the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword is not well supported by most C/C++ implementations - even for portable uses according to the C and C++ standards. Most C/C++ implementations are buggy regarding the behavior of the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword.&amp;lt;ref&amp;gt;{{Cite journal |last1=Eide |first1=Eric |last2=Regehr |first2=John |date=October 2008 |title=Volatiles Are Miscompiled, and What to Do about It |url=https://users.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf |journal=Proceedings of the Eighth ACM and IEEE International Conference on Embedded Software (EMSOFT), Atlanta, Georgia, USA |via=cs.utah.edu}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{Cite web |title=Volatile Bugs, Three Years Later – Embedded in Academia |url=https://blog.regehr.org/archives/503 |access-date=2024-08-28 |website=blog.regehr.org}}&amp;lt;/ref&amp;gt; Programmers should take great care whenever using the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword in C and C++.&lt;br /&gt;
&lt;br /&gt;
==In Java==&lt;br /&gt;
In all modern versions of the [[Java programming language]], the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword gives the following guarantees:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes are [[atomic operation|atomic]]. In particular, reads and writes to &amp;lt;code&amp;gt;long&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt; fields will not tear. (The [[atomic operation|atomic]] guarantee applies only to the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; primitive value or the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reference value, and &amp;#039;&amp;#039;not&amp;#039;&amp;#039; to any Object value.)&lt;br /&gt;
* There is a single global ordering of all &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes. In other words, a &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; read will read the current value (and not a past or future value), and all &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads will agree on a single global order of &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; writes.&lt;br /&gt;
* &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes have &amp;quot;acquire&amp;quot; and &amp;quot;release&amp;quot; [[memory barrier]] semantics (known in the Java standard as [[happened-before|happens-before]]).&amp;lt;ref&amp;gt;Section 17.4.4: Synchronization Order&lt;br /&gt;
{{cite web |year=2013 |title=The Java® Language Specification, Java SE 7 Edition |url=http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.4 |access-date=2013-05-12 |publisher=[[Oracle Corporation]]}}&amp;lt;/ref&amp;gt;&amp;lt;ref&amp;gt;{{cite web |date=2021-03-08 |title=Java Concurrency: Understanding the &amp;#039;Volatile&amp;#039; Keyword |url=https://dzone.com/articles/java-concurrency-understanding-the-volatile-keyword |archive-url=https://web.archive.org/web/20210509104459/https://dzone.com/articles/java-concurrency-understanding-the-volatile-keyword |archive-date=2021-05-09 |access-date=2021-05-09 |publisher=dzone.com}}&amp;lt;/ref&amp;gt; In other words, &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; provides guarantees about the relative order of &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; and non-&amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes. In other words, &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; basically provides the same memory visibility guarantees as a Java [[lock (computer science)|synchronized block]] (but without the [[mutual exclusion]] guarantees of a [[lock (computer science)|synchronized block]]).&lt;br /&gt;
&lt;br /&gt;
Together, these guarantees make &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; into a useful [[thread (computing)|multi-threading]] construct in [[Java programming language|Java]]. In particular, the typical [[double-checked locking]] algorithm with &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; works correctly in [[Java programming language|Java]].&amp;lt;ref&amp;gt;{{cite web |author1=Neil Coffey |title=Double-checked Locking (DCL) and how to fix it |url=http://www.javamex.com/tutorials/double_checked_locking_fixing.shtml |access-date=2009-09-19 |publisher=Javamex}}&amp;lt;/ref&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Early versions of Java ===&lt;br /&gt;
Before Java version 5, the Java standard did not guarantee the relative ordering of &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; and non-&amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; reads and writes. In other words, &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; did not have &amp;quot;acquire&amp;quot; and &amp;quot;release&amp;quot; [[memory barrier]] semantics. This greatly limited its use as a [[thread (computing)|multi-threading]] construct. In particular, the typical [[double-checked locking]] algorithm with &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; did &amp;#039;&amp;#039;not&amp;#039;&amp;#039; work correctly.&lt;br /&gt;
&lt;br /&gt;
==In C#==&lt;br /&gt;
&lt;br /&gt;
In [[C Sharp (programming language)|C#]], &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; ensures that code accessing the field is not subject to some thread-unsafe optimizations that may be performed by the compiler, the CLR, or by hardware. When a field is marked &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt;, the compiler is instructed to generate a &amp;quot;memory barrier&amp;quot; or &amp;quot;fence&amp;quot; around it, which prevents instruction reordering or caching tied to the field. When reading a &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; field, the compiler generates an &amp;#039;&amp;#039;acquire-fence&amp;#039;&amp;#039;, which prevents other reads and writes to the field from being moved &amp;#039;&amp;#039;before&amp;#039;&amp;#039; the fence. When writing to a &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; field, the compiler generates a &amp;#039;&amp;#039;release-fence&amp;#039;&amp;#039;; this fence prevents other reads and writes to the field from being moved &amp;#039;&amp;#039;after&amp;#039;&amp;#039; the fence.&amp;lt;ref name=&amp;quot;Albahari&amp;quot;&amp;gt;{{cite web |last1=Albahari |first1=Joseph |title=Part 4: Advanced Threading |url=http://www.albahari.com/threading/part4.aspx |website=Threading in C# |publisher=O&amp;#039;Reilly Media |access-date=9 December 2019 |archive-url=https://web.archive.org/web/20191212032535/http://www.albahari.com/threading/part4.aspx#_Nonblocking_Synchronization |archive-date=12 December 2019 |url-status=bot: unknown }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only the following types can be marked &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt;: all reference types, &amp;lt;code&amp;gt;Single&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Boolean&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Byte&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;SByte&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Int16&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UInt16&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Int32&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UInt32&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Char&amp;lt;/code&amp;gt;, and all [[Enumerated type|enumerated types]] with an underlying type of &amp;lt;code&amp;gt;Byte&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;SByte&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Int16&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UInt16&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Int32&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;UInt32&amp;lt;/code&amp;gt;.&amp;lt;ref&amp;gt;{{cite book |last1=Richter |first1=Jeffrey |title=CLR Via C# |url=https://archive.org/details/clrviac00rich_000 |url-access=limited |publisher=Microsoft Press |date=February 11, 2010 |pages=[https://archive.org/details/clrviac00rich_000/page/n200 183] |chapter=Chapter 7: Constants and Fields |isbn=978-0-7356-2704-8}}&amp;lt;/ref&amp;gt; (This excludes value [[struct]]s, as well as the primitive types &amp;lt;code&amp;gt;Double&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Int64&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;UInt64&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Decimal&amp;lt;/code&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
Using the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword does not support fields that are [[Evaluation strategy#Call by reference|passed by reference]] or [[Closure (computer programming)|captured local variables]]; in these cases, &amp;lt;code&amp;gt;Thread.VolatileRead&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Thread.VolatileWrite&amp;lt;/code&amp;gt; must be used instead.&amp;lt;ref name=&amp;quot;Albahari&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In effect, these methods disable some optimizations usually performed by the C# compiler, the JIT compiler, or the CPU itself. The guarantees provided by &amp;lt;code&amp;gt;Thread.VolatileRead&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Thread.VolatileWrite&amp;lt;/code&amp;gt; are a superset of the guarantees provided by the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword: instead of generating a &amp;quot;half fence&amp;quot; (ie an acquire-fence only prevents instruction reordering and caching that comes before it), &amp;lt;code&amp;gt;VolatileRead&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;VolatileWrite&amp;lt;/code&amp;gt; generate a &amp;quot;full fence&amp;quot; which prevent instruction reordering and caching of that field in both directions.&amp;lt;ref name=&amp;quot;Albahari&amp;quot;/&amp;gt; These methods work as follows:&amp;lt;ref&amp;gt;{{cite book |last1=Richter |first1=Jeffrey |title=CLR Via C# |url=https://archive.org/details/clrviac00rich_000 |url-access=limited |publisher=Microsoft Press |date=February 11, 2010 |pages=[https://archive.org/details/clrviac00rich_000/page/n814 797]–803 |chapter=Chapter 28: Primitive Thread Synchronization Constructs |isbn=978-0-7356-2704-8}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
*The &amp;lt;code&amp;gt;Thread.VolatileWrite&amp;lt;/code&amp;gt; method forces the value in the field to be written to at the point of the call. In addition, any earlier program-order loads and stores must occur before the call to &amp;lt;code&amp;gt;VolatileWrite&amp;lt;/code&amp;gt; and any later program-order loads and stores must occur after the call.&lt;br /&gt;
*The &amp;lt;code&amp;gt;Thread.VolatileRead&amp;lt;/code&amp;gt; method forces the value in the field to be read from at the point of the call. In addition, any earlier program-order loads and stores must occur before the call to &amp;lt;code&amp;gt;VolatileRead&amp;lt;/code&amp;gt; and any later program-order loads and stores must occur after the call.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Thread.VolatileRead&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Thread.VolatileWrite&amp;lt;/code&amp;gt; methods generate a full fence by calling the &amp;lt;code&amp;gt;Thread.MemoryBarrier&amp;lt;/code&amp;gt; method, which constructs a memory barrier that works in both directions. In addition to the motivations for using a full fence given above, one potential problem with the &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; keyword that is solved by using a full fence generated by &amp;lt;code&amp;gt;Thread.MemoryBarrier&amp;lt;/code&amp;gt; is as follows: due to the asymmetric nature of half fences, a &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; field with a write instruction followed by a read instruction may still have the execution order swapped by the compiler. Because full fences are symmetric, this is not a problem when using &amp;lt;code&amp;gt;Thread.MemoryBarrier&amp;lt;/code&amp;gt;.&amp;lt;ref name=&amp;quot;Albahari&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==In Fortran==&lt;br /&gt;
&amp;lt;code&amp;gt;VOLATILE&amp;lt;/code&amp;gt; is part of the [[Fortran#Fortran 2003|Fortran 2003]] standard,&amp;lt;ref&amp;gt;{{cite web|url=http://docs.cray.com/books/S-3692-51/html-S-3692-51/zfixedn3c8sk4c.html|title=VOLATILE Attribute and Statement|publisher=Cray|access-date=2016-04-22|archive-date=2018-01-23|archive-url=https://web.archive.org/web/20180123165050/http://docs.cray.com/books/S-3692-51/html-S-3692-51/zfixedn3c8sk4c.html|url-status=dead}}&amp;lt;/ref&amp;gt; although earlier version supported it as an extension. Making all variables &amp;lt;code&amp;gt;volatile&amp;lt;/code&amp;gt; in a function is also useful finding [[aliasing (computing)|aliasing]] related bugs.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;fortran&amp;quot;&amp;gt;&lt;br /&gt;
integer, volatile :: i ! When not defined volatile the following two lines of code are identical&lt;br /&gt;
write(*,*) i**2  ! Loads the variable i once from memory and multiplies that value times itself&lt;br /&gt;
write(*,*) i*i   ! Loads the variable i twice from memory and multiplies those values&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By always &amp;quot;drilling down&amp;quot; to memory of a VOLATILE, the Fortran compiler is precluded from reordering reads or writes to volatiles. This makes visible to other threads actions done in this thread, and vice versa.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
|url=https://software.intel.com/en-us/forums/intel-moderncode-for-parallel-architectures/topic/279191&lt;br /&gt;
|title=Volatile and shared array in Fortran |website=Intel.com}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use of VOLATILE reduces and can even prevent optimization.&amp;lt;ref&amp;gt;{{cite web&lt;br /&gt;
|url=https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnbq/index.html&lt;br /&gt;
|title=VOLATILE  |website=Oracle.com}}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Reflist|30em}}&lt;br /&gt;
&lt;br /&gt;
==External links==&lt;br /&gt;
*[http://www.adaic.com/standards/05rm/html/RM-C-6.html Ada Reference Manual C.6: Shared Variable Control]&lt;br /&gt;
*[https://web.archive.org/web/20160304053622/https://www.kernel.org/doc/Documentation/volatile-considered-harmful.txt Linux kernel: volatile-considered-harmful]&lt;br /&gt;
&lt;br /&gt;
[[Category:C (programming language)]]&lt;br /&gt;
[[Category:Concurrency control]]&lt;br /&gt;
[[Category:Variable (computer science)]]&lt;/div&gt;</summary>
		<author><name>2A02:A447:765F:0:0:0:0:169B</name></author>
	</entry>
</feed>