Why is volatile
needed in C? What is it used for? What will it do?

- 730,956
- 141
- 904
- 1,278
-
2[http://stackoverflow.com/questions/72552/c-when-has-the-volatile-keyword-ever-helped-you](http://stackoverflow.com/questions/72552/c-when-has-the-volatile-keyword-ever-helped-you) – Frederik Slijkerman Oct 29 '08 at 08:45
-
Related: [When to use volatile with multi threading?](https://stackoverflow.com/a/58535118) applies to C11 and later as well. It's *not* needed for that, but was used until C11 gave a fully standardized way to do lock-free atomic load/store. – Peter Cordes Jul 05 '22 at 14:42
-
Similar for [C#](https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29) and [Java](https://en.wikipedia.org/wiki/Java_%28programming_language%29): *[What is the "volatile" keyword used for?](https://stackoverflow.com/questions/3430757/what-is-the-volatile-keyword-used-for)* – Peter Mortensen Jun 19 '23 at 14:48
-
An even earlier one (2008-09-16): [Why does volatile exist?](https://stackoverflow.com/questions/72552/why-does-volatile-exist) – Peter Mortensen Jun 19 '23 at 15:14
18 Answers
volatile
tells the compiler not to optimize anything that has to do with the volatile
variable.
There are at least three common reasons to use it, all involving situations where the value of the variable can change without action from the visible code:
- When you interface with hardware that changes the value itself
- when there's another thread running that also uses the variable
- when there's a signal handler that might change the value of the variable.
Let's say you have a little piece of hardware that is mapped into RAM somewhere and that has two addresses: a command port and a data port:
typedef struct
{
int command;
int data;
int isBusy;
} MyHardwareGadget;
Now you want to send some command:
void SendCommand (MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isbusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}
Looks easy, but it can fail because the compiler is free to change the order in which data and commands are written. This would cause our little gadget to issue commands with the previous data-value. Also take a look at the wait while busy loop. That one will be optimized out. The compiler will try to be clever, read the value of isBusy
just once and then go into an infinite loop. That's not what you want.
The way to get around this is to declare the pointer gadget
as volatile
. This way the compiler is forced to do what you wrote. It can't remove the memory assignments, it can't cache variables in registers and it can't change the order of assignments either
This is the correct version:
void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)
{
// wait while the gadget is busy:
while (gadget->isBusy)
{
// do nothing here.
}
// set data first:
gadget->data = data;
// writing the command starts the action:
gadget->command = command;
}

- 16,517
- 6
- 42
- 66

- 83,631
- 31
- 151
- 221
-
60Personally, I'd prefer the integer size to be explicity e.g. int8/int16/int32 when talking to hardware. Nice answer though ;) – tonylo Oct 29 '08 at 08:53
-
31yes, you should declare things with a fixed register size, but hey - it's just an example. – Nils Pipenbrinck Oct 29 '08 at 08:54
-
77Volatile is also needed in threaded code when you are playing with data that isn't concurrency protected. And yes there are valid times to be doing that, you can for example write a thread safe circular message queue without needing explicit concurrency protection, but it will need volatiles. – Gordon Wrigley Oct 29 '08 at 09:57
-
21Read the C specification harder. Volatile only has defined behavior on memory-mapped device I/O or memory touched by an asynchronous interrupting function. It says *nothing* about threading, and a compiler which optimizes away access to memory touched by multiple threads is conformant. – ephemient Oct 29 '08 at 14:36
-
15Do you have a reference for that claim? Every reference I've seen says volatile tells the compiler not to optimize memory accesses on whatever. I've never seen a restriction on whether the memory is RAM or IO. Further on many platforms the compiler can't distinguish between RAM and memory mapped IO. – Gordon Wrigley Oct 29 '08 at 22:28
-
4In signal handlers, one of the few things it is truly safe to do is set a global variable of the type 'volatile sigatomic_t'. Also, where setjmp() is used, you should worry about which local variables are marked volatile. – Jonathan Leffler Nov 01 '08 at 00:47
-
14Instead of saying `volatile` is used "when you interface with hardware", I would say "when the variable can be altered by something outside of your program". This covers the memory-mapped hardware case as well as shared memory, etc. – bta May 21 '10 at 19:59
-
1I'm not as familiar with C, but in C++ volatile memory accesses are defined as observable behavior, and therefore have to be executed as written and without any reordering. That will apply to shared memory in threaded code as well as memory-mapped I/O. – David Thornley Jul 27 '10 at 15:04
-
5If you use volatile for concurrency instead of atomic variables or mutexes, you better know really well what you are doing. – ninjalj Jul 27 '10 at 15:08
-
5To explain better what Jonathan Leffler said, variables local to the function that called setjmp() that have been changed between the setjmp() and longjmp() calls, have undefined values unless declared volatile. – ninjalj Jul 27 '10 at 15:12
-
7@DavidThornley, @tolomea: While the volatile memory access is defined as observable behaviour that has to be executed as written and without reordering, it's not defined that it's also performed atomically. Which it simply does not have to. That's why C++11 introduces the `std::atomic` types, which have stronger guarantees. See [N2016](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html) for discussion about `volatile` and threads (whitepaper from C++11 standardization process). – Jan Hudec Jan 16 '12 at 18:12
-
6@JanHudec: And to clarify, they only have to maintain order between other `volatile` variables. They don't act as memory barriers. – GManNickG May 03 '12 at 23:27
-
27@tolomea : completely wrong. sad 17 persons don't know it. volatile is not a memory fence. it is only related to __avoiding code elision during optimization based on assumption of non visible side effects__. – v.oddou Sep 13 '13 at 03:21
-
13the answer is false in many ways, for example `volatile` variables do exist in registers. notably `volatile` is indeed useful on memory mapped registers. crazy this answer has 67 upvotes... The next wrong thing is the re-ordering guarantee, please read http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming – v.oddou Sep 13 '13 at 03:44
-
2@NilsPipenbrinck does `volatile MyHardwareGadget * gadget` declare the value pointed by gadget is **volatile** instead of the pointer? or I am wrong? – StrikeW Jun 17 '15 at 09:40
-
As others have commented, you forgot to mention another crucial use of the keyword, i.e: multi threaded programming. It will prevent the compiler from caching the marked variable by any means when it thinks it can do so based solely on the local vicinity of the code where that variable is used (think a shared counter or similar). – n00bmind May 03 '19 at 13:23
-
5-1 Volatile does NOT guarantee ordering (e.g. "memory fence"). You must use something like ```std::atomic``` to achieve that, or rely on a compiler macro that will implement the hardware-specific memory fence behind the scenes. – abc Feb 27 '20 at 15:39
-
4"Volatile tells the compiler not to optimize anything that has to do with the volatile variable." the first line is already wrong. – qwr Jul 06 '20 at 21:38
-
How can one say that the "compiler caches a variable"? Isn't that the CPU:s job? The compiler has no active participation during run time ... – Abdel Aleem May 05 '21 at 10:32
-
1Abdel, you're confusing the CPU's caches, which cache RAM, and C variable caching. In this case, the compiler can cache a commonly-used variable in a CPU register. Particularly if the CPU has a lot of registers available, ARM chips being an example of that. If the compiler thinks it can speed up some code by putting an often-accessed variable in a register, it often will. If some other hardware or software is expecting the variable to be read / written from a RAM location, and code is ignoring it, instead using a register, then problems can happen. – Greenaum Nov 03 '21 at 08:14
volatile
in C actually came into existence for the purpose of not caching the values of the variable automatically. It will tell the compiler not to cache the value of this variable. So it will generate code to take the value of the given volatile
variable from the main memory every time it encounters it. This mechanism is used because at any time the value can be modified by the OS or any interrupt. So using volatile
will help us accessing the value afresh every time.

- 6,221
- 16
- 30

- 13,579
- 15
- 42
- 45
-
1Came into existence? Wasn't ´volatile` originally borrowed from C++? Well, I seem to remember... – syntaxerror Jan 25 '16 at 04:51
-
2This is not volatile all about - it also prohibit some reordering if specified as volatile.. – FaceBro Jun 07 '16 at 14:25
-
6@FaceBro: The purpose of `volatile` was to make it possible for compilers to optimize code while still allowing programmers to achieve the semantics that would be achieved without such optimizations. The authors of the Standard expected that quality implementations would support whatever semantics were useful given their target platforms and application fields, and didn't expect that compiler writers would seek to offer the lowest quality semantics that conform to the Standard and weren't 100% stupid (note that the authors of the Standard explicitly recognize in the rationale... – supercat Jun 07 '18 at 22:43
-
1...that it's possible for an implementation to be conforming without being of good enough quality to actually be suitable for any purpose, but they didn't think it necessary to prevent that). – supercat Jun 07 '18 at 22:45
-
3@syntaxerror how can it be borrowed from C++ when C was more than a decade older than C++ (both on first releases and first standards)? – phuclv Aug 09 '18 at 02:28
-
1How can one say that the "compiler caches a variable"? Isn't that the CPU:s job? The compiler has no active participation during run time ... – Abdel Aleem May 05 '21 at 10:32
-
Volatile will prevent the compiler from optimizing out a load or a store, but it will not prevent the cache line containing the field being accessed, from being cached. Mechanisms like PAT and MTTR are needed for that to make a page or a region of memory uncachable. – pveentjer Nov 30 '21 at 09:35
-
-
MTRR = [memory type range register](https://en.wikipedia.org/wiki/Memory_type_range_register) – Peter Mortensen Jun 18 '23 at 18:42
-
PAT = [page attribute table](https://en.wikipedia.org/wiki/Page_attribute_table) – Peter Mortensen Jun 18 '23 at 18:43
Another use for volatile
is signal handlers. If you have code like this:
int quit = 0;
while (!quit)
{
/* very small loop which is completely visible to the compiler */
}
The compiler is allowed to notice the loop body does not touch the quit
variable and convert the loop to a while (true)
loop. Even if the quit
variable is set on the signal handler for SIGINT
and SIGTERM
; the compiler has no way to know that.
However, if the quit
variable is declared volatile
, the compiler is forced to load it every time, because it can be modified elsewhere. This is exactly what you want in this situation.
-
1when you say "the compiler is forced to load it every time, is it like when compiler decide to optimize a certain variable and we don't declare the variable as volatile, at run time that certain variable is loaded to CPU registers not in memory? – Amit Singh Tomar Mar 17 '15 at 16:34
-
3@AmitSinghTomar It means what it says: Every time the code checks the value, it is reloaded. Otherwise, the compiler is allowed to assume that functions that don't take a reference to the variable can't modify it, so assuming as CesarB intended that the above loop does not set `quit`, the compiler can optimise it into a constant loop, assuming that there's no way for `quit` to be changed between iterations. N.B.: This isn't necessarily a good substitute for actual threadsafe programming. – underscore_d Jul 02 '16 at 14:46
-
if quit is a global variable, then the compiler shall not optimize the while loop, correct ? – Pierre G. Aug 20 '16 at 13:47
-
5@PierreG. No, the compiler can always assume that the code is single-threaded, unless told otherwise. That is, in the absence of `volatile` or other markers, it will assume that nothing outside the loop modifies that variable once it enters the loop, even if it's a global variable. – CesarB Sep 12 '16 at 12:37
-
thx CesarB. so in that case, can the compiler optimize a while like this : while(gloval_variable <> 0) {} and make this loop lock forever ? – Pierre G. Sep 12 '16 at 12:46
-
2@PierreG. Yes, try for instance compiling `extern int global; void fn(void) { while (global != 0) { } }` with `gcc -O3 -S` and look at the resulting assembly file, on my machine it does `movl global(%rip), %eax`; `testl %eax, %eax`; `je .L1`; `.L4: jmp .L4`, that is, an infinite loop if the global is not zero. Then try adding `volatile` and see the difference. – CesarB Sep 12 '16 at 13:00
-
@CesarB In practice, if the body of the loop is non trivial and calls external functions, and if the flag is a global variable, then the compiler will probably assume that the call to functions can change the variable. – curiousguy Jun 28 '18 at 02:29
-
How can one say that the "compiler loads a variable"? Isn't that the CPU:s job? The compiler has no active participation during run time ... – Abdel Aleem May 05 '21 at 10:33
-
Another thing I can't quite wrap my head around: I guess the 'quit' variable is non-stack, i.e. global. It is probably referenced in an ISR right? Can't the compiler understand that it is being assigned in that ISR and is hence (potentially) modified by the visible code (so volatile qualifier becomes unnecessary)? – Abdel Aleem May 05 '21 at 10:39
volatile
tells the compiler that your variable may be changed by other means, than the code that is accessing it. e.g., it may be a I/O-mapped memory location. If this is not specified in such cases, some variable accesses can be optimised, e.g., its contents can be held in a register, and the memory location not read back in again.

- 219,335
- 46
- 382
- 435
-
changed particularly by hardware or other programs / drivers, and when this is intentional behaviour, you make it volatile to inform the compiler not to optimise out accesses to the memory address – Lewis Kelsey Aug 11 '22 at 16:01
See this article by Andrei Alexandrescu, "volatile - Multithreaded Programmer's Best Friend"
The volatile keyword was devised to prevent compiler optimizations that might render code incorrect in the presence of certain asynchronous events. For example, if you declare a primitive variable as volatile, the compiler is not permitted to cache it in a register -- a common optimization that would be disastrous if that variable were shared among multiple threads. So the general rule is, if you have variables of primitive type that must be shared among multiple threads, declare those variables volatile. But you can actually do a lot more with this keyword: you can use it to catch code that is not thread safe, and you can do so at compile time. This article shows how it is done; the solution involves a simple smart pointer that also makes it easy to serialize critical sections of code.
The article applies to both C and C++.
Also see the article "C++ and the Perils of Double-Checked Locking" by Scott Meyers and Andrei Alexandrescu:
So when dealing with some memory locations (e.g. memory mapped ports or memory referenced by ISRs [ Interrupt Service Routines ] ), some optimizations must be suspended. volatile exists for specifying special treatment for such locations, specifically: (1) the content of a volatile variable is "unstable" (can change by means unknown to the compiler), (2) all writes to volatile data are "observable" so they must be executed religiously, and (3) all operations on volatile data are executed in the sequence in which they appear in the source code. The first two rules ensure proper reading and writing. The last one allows implementation of I/O protocols that mix input and output. This is informally what C and C++'s volatile guarantees.

- 30,738
- 21
- 105
- 131

- 39,711
- 30
- 131
- 179
-
1Does the standard specify whether a read is considered 'observable behavior' if the value is never used? My impression is that it should be, but when I claimed it was elsewhere someone challenged me for a citation. It seems to me that on any platform where a read of a volatile variable could conceivably have any effect, a compiler should be required generate code that performs every indicated read precisely once; without that requirement, it would be difficult to write code which generated a predictable sequence of reads. – supercat Oct 13 '10 at 22:50
-
@supercat: According to the first article, "If you use the volatile modifier on a variable, the compiler won't cache that variable in registers — each access will hit the actual memory location of that variable." Also, in section §6.7.3.6 of the c99 standard it says: "An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects." It further implies that volatile variables may not be cached in registers and that all reads and writes must be executed in order relative to sequence points, that they are in fact observable. – Robert S. Barnes Oct 14 '10 at 08:28
-
The latter article indeed states explicitly that reads are side-effects. The former indicates that reads cannot be performed out of sequence, but did not seem to preclude the possibility of them being elided altogether. – supercat Oct 14 '10 at 20:31
-
"the compiler is not permitted to cache it in a register" - Most RISC arcitectures ae register-machines, so any read-modify-write **has** to cache the object in a registers. `volatile` does not guarantee atomicity. – too honest for this site May 22 '17 at 17:43
-
2@Olaf: Loading something into a register is not the same thing as caching. Caching would affect the number of loads or stores or their timing. – supercat Jun 07 '18 at 22:47
-
@supercat: I seem to have completely missed caching disallows to not prevent loads/stores. Anyway, I should have used a better term here indeed. If I just knew one. Nevertheless it should be clear from the context what I mean. Plus there is no guarantee a `volatile` is not held in a register. In fact the abstract machine allows a lot of optimisations even for `volatile`s. – too honest for this site Jun 07 '18 at 23:01
-
1@Olaf: The Standard makes no attempt to specify what `volatile` behavior would be necessary to make an implementation suitable for any particular purpose, such as programming a particular *real* machine. Instead, it expects implementers to recognize the ways in which the real target machine may differ from the abstract one, and thus recognize what semantics users of particular platforms will need and give it to them. On a hardware platform where a load or store may trigger actions that affect program execution, a quality implementation should treat such actions as... – supercat Jun 08 '18 at 15:03
-
1...though they could calls unknown functions [since they very well might], but the authors of gcc and clang seem to think that since such things don't happen on the "abstract machine", there's no reason they should allow for such possibilities when targeting a real one. – supercat Jun 08 '18 at 15:06
My simple explanation is:
In some scenarios, based on the logic or code, the compiler will do optimisation of variables which it thinks do not change. The volatile
keyword prevents a variable being optimised.
For example:
bool usb_interface_flag = 0;
while(usb_interface_flag == 0)
{
// execute logic for the scenario where the USB isn't connected
}
From the above code, the compiler may think usb_interface_flag
is defined as 0, and that in the while loop it will be zero forever. After optimisation, the compiler will treat it as while(true)
all the time, resulting in an infinite loop.
To avoid these kinds of scenarios, we declare the flag as volatile, we are telling to compiler that this value may be changed by an external interface or other module of program, i.e., please don't optimise it. That's the use case for volatile.

- 404
- 1
- 5
- 21

- 453
- 4
- 6
A marginal use for volatile is the following. Say you want to compute the numerical derivative of a function f
:
double der_f(double x)
{
static const double h = 1e-3;
return (f(x + h) - f(x)) / h;
}
The problem is that x+h-x
is generally not equal to h
due to roundoff errors. Think about it : when you substract very close numbers, you lose a lot of significant digits which can ruin the computation of the derivative (think 1.00001 - 1). A possible workaround could be
double der_f2(double x)
{
static const double h = 1e-3;
double hh = x + h - x;
return (f(x + hh) - f(x)) / hh;
}
but depending on your platform and compiler switches, the second line of that function may be wiped out by a aggressively optimizing compiler. So you write instead
volatile double hh = x + h;
hh -= x;
to force the compiler to read the memory location containing hh, forfeiting an eventual optimization opportunity.

- 55,948
- 11
- 128
- 197
-
What is a difference between using `h` or `hh` in derivative formula? When `hh` is computed the last formula uses it like the first one, with no difference. Maybe it should be `(f(x+h) - f(x))/hh`? – Sergey Zhukov Sep 22 '14 at 06:02
-
2The difference between `h` and `hh` is that `hh` is truncated to some negative power of two by the operation `x + h - x`. In this case, `x + hh` and `x` differ exactly by `hh`. You can also take your formula, it will give the same result, since `x + h` and `x + hh` are equal (it is the denominator which is important here). – Alexandre C. Sep 22 '14 at 18:16
-
3Isn't more readable way to write this would be `x1=x+h; d = (f(x1)-f(x))/(x1-x)`? without using the volatile. – Sergey Zhukov Sep 24 '14 at 19:19
-
Any reference that a compiler can wipe out that second line of the function? – CoffeeTableEspresso Sep 25 '18 at 00:06
-
@CoffeeTableEspresso : Nope, sorry. The more I know about floating point, the more I believe that the compiler is only allowed to optimize it if explicitely told so, with `-ffast-math` or equivalent. – Alexandre C. Sep 25 '18 at 19:53
There are two uses. These are specially used more often in embedded development.
The compiler will not optimise the functions that use variables that are defined with the volatile keyword
Volatile is used to access exact memory locations in RAM, ROM, etc... This is used more often to control memory-mapped devices, access CPU registers and locate specific memory locations.
See examples with assembly listing. Re: Usage of C "volatile" Keyword in Embedded Development

- 30,738
- 21
- 105
- 131

- 127
- 1
- 2
-
2"Compiler will not optimise the functions that uses variables that are defined with volatile keyword" - that's plain wrong. – too honest for this site May 22 '17 at 17:46
-
Additionally, `volatile` can be used to force memory reads or writes to be a particular size. For example, there can be 8-bit only memory, or 16-bit only memory, and a read or write of the wrong type will have an undesirable effect. Without `volatile`, the compiler is free to combine four 8-bit writes into a 32-bit write, even if the memory does not support that kind of write. There are even cases where a `for` loop gets changed into `memset` which attempts to write bytes to 16-bit only memory, but this disappears when using `volatile`. – Dwedit May 22 '22 at 18:33
I'll mention another scenario where volatiles are important.
Suppose you memory-map a file for faster I/O and that file can change behind the scenes (e.g. the file is not on your local hard drive, but is instead served over the network by another computer).
If you access the memory-mapped file's data through pointers to non-volatile objects (at the source code level), then the code generated by the compiler can fetch the same data multiple times without you being aware of it.
If that data happens to change, your program may become using two or more different versions of the data and get into an inconsistent state. This can lead not only to logically incorrect behavior of the program but also to exploitable security holes in it if it processes untrusted files or files from untrusted locations.
If you care about security, and you should, this is an important scenario to consider.

- 61,140
- 12
- 83
- 180
Volatile is also useful, when you want to force the compiler not to optimize a specific code sequence (e.g. for writing a micro-benchmark).

- 18,734
- 5
- 61
- 83
In the language designed by Dennis Ritchie, every access to any object, other than automatic objects whose address had not been taken, would behave as though it computed the address of the object and then read or wrote the storage at that address. This made the language very powerful, but severely limited optimization opportunities.
While it might have been possible to forbid compilers from assuming that addressable objects would never be changed in weird ways, such an assumption would be have appropriate and useful for the vast majority of objects in C programs, and it would have been impractical to add a qualifier to all the objects for which such assumption would be appropriate. On the other hand, some programs need to use some objects for which such an assumption would not hold. To resolve this issue, the Standard says that compilers may assume that objects which are not declared volatile
will not have their value observed or changed in ways that are outside the compiler's control, or would be outside a reasonable compiler's understanding.
Because various platforms may have different ways in which objects could be observed or modified outside a compiler's control, it is appropriate that quality compilers for those platforms should differ in their exact handling of volatile
semantics. Unfortunately, because the Standard failed to suggest that quality compilers intended for low-level programming on a platform should handle volatile
in a way that will recognize any and all relevant effects of a particular read/write operation on that platform, many compilers fall short of doing so in ways that make it harder to process things like background I/O in a way which is efficient but can't be broken by compiler "optimizations".

- 77,689
- 9
- 166
- 211
-
The sentence starting with *"While it might have"* does not read well. For instance, do you mean *"such an assumption would be* ***inappropriate"***? Perhaps rephrase? – Peter Mortensen Jun 18 '23 at 19:51
-
@PeterMortensen: Yeah, that was a bit of a jumbly mess. Hopefully it's better now. – supercat Jun 19 '23 at 19:19
In my opinion, you should not expect too much from volatile
. To illustrate, look at the example in Nils Pipenbrinck's highly-voted answer.
I would say, his example is not suitable for volatile
. volatile
is only used to:
prevent compiler optimizations that would normally be useful and desirable. It is nothing about thread safety, atomic access or even memory order.
In that example:
void SendCommand (volatile MyHardwareGadget * gadget, int command, int data)
{
// Wait while the gadget is busy:
while (gadget->isbusy)
{
// Do nothing here.
}
// Set data first:
gadget->data = data;
// Writing the command starts the action:
gadget->command = command;
}
The gadget->data = data
before gadget->command = command
only is only guaranteed in the compiled code by the compiler.
At run time, the processor may still reorder the data and command assignment, depending on the processor architecture. The hardware could get the wrong data (suppose a gadget is mapped to hardware I/O). A memory barrier is needed between data and command assignment.

- 42,793
- 6
- 62
- 96

- 89
- 1
- 4
-
4I'd say volatile is used to prevent the compiler from making optimizations that would *normally* be useful and desirable. As written, it sounds like `volatile` is degrading the performance for no reason. As for whether it is sufficient, that will depend upon other aspects of the system that the programmer may know more about than the compiler. On the other hand, if a processor guarantees that an instruction to write to a certain address will flush the CPU cache but a compiler provided no way to flush register-cached variables the CPU knows nothing about, flushing the cache would be useless. – supercat Feb 19 '17 at 01:28
volatile means the storage is likely to change at any time and be changed by something outside the control of the user program.
This means that if you reference the variable, the program should always check the physical address (i.e., a mapped input FIFO), and not use it in a cached way.

- 30,738
- 21
- 105
- 131

- 125
- 2
- 1
-
2No compiler takes volatile to mean either "physical address in RAM" or "bypass the cache". – curiousguy Jun 28 '18 at 01:33
In simple terms, it tells the compiler not to do any optimisation on a particular variable. Variables which are mapped to device register are modified indirectly by the device. In this case, volatile must be used.

- 169
- 1
- 6
-
4Is there anything new in this answer which has not been mentioned before? – slfan Oct 22 '18 at 17:53
Wikipedia says everything about volatile
:
And the Linux kernel's documentation also makes a excellent note about volatile
:

- 30,738
- 21
- 105
- 131

- 3,746
- 4
- 50
- 67
A volatile can be changed from outside the compiled code (for example, a program may map a volatile variable to a memory mapped register).
The compiler won't apply certain optimizations to code that handles a volatile variable. For example, it won't load it into a register without writing it to memory. This is important when dealing with hardware registers.

- 30,738
- 21
- 105
- 131

- 6,777
- 6
- 36
- 51
As rightly suggested by many here, the volatile keyword's popular use is to skip the optimisation of the volatile variable.
The best advantage that comes to mind, and worth mentioning after reading about volatile is -- to prevent rolling back of the variable in case of a longjmp
. A non-local jump.
What does this mean?
It simply means that the last value will be retained after you do stack unwinding, to return to some previous stack frame; typically in case of some erroneous scenario.
Since it'd be out of scope of this question, I am not going into details of setjmp/longjmp
here, but it's worth reading about it; and how the volatility feature can be used to retain the last value.

- 321
- 1
- 5
-
Re *"out of scope of this question"*: No, please provide a code example. – Peter Mortensen Jun 18 '23 at 19:54
It does not allow the compiler to automatically change values of variables. A volatile variable is for dynamic use.

- 30,738
- 21
- 105
- 131

- 11