511

Possible Duplicate:
Why does volatile exist?

I have never used it but I wonder why people use it? What does it exactly do? I searched the forum, I found it only C# or Java topics.

Michael M.
  • 10,486
  • 9
  • 18
  • 34
Nawaz
  • 353,942
  • 115
  • 666
  • 851

2 Answers2

1477

Consider this code,

int some_int = 100;

while(some_int == 100)
{
   //your code
}

When this program gets compiled, the compiler may optimize this code, if it finds that the program never ever makes any attempt to change the value of some_int, so it may be tempted to optimize the while loop by changing it from while(some_int == 100) to something which is equivalent to while(true) so that the execution could be fast (since the condition in while loop appears to be true always). (if the compiler doesn't optimize it, then it has to fetch the value of some_int and compare it with 100, in each iteration which obviously is a little bit slow.)

However, sometimes, optimization (of some parts of your program) may be undesirable, because it may be that someone else is changing the value of some_int from outside the program which compiler is not aware of, since it can't see it; but it's how you've designed it. In that case, compiler's optimization would not produce the desired result!

So, to ensure the desired result, you need to somehow stop the compiler from optimizing the while loop. That is where the volatile keyword plays its role. All you need to do is this,

volatile int some_int = 100; //note the 'volatile' qualifier now!

In other words, I would explain this as follows:

volatile tells the compiler that,

"Hey compiler, I'm volatile and, you know, I can be changed by some XYZ that you're not even aware of. That XYZ could be anything. Maybe some alien outside this planet called program. Maybe some lightning, some form of interrupt, volcanoes, etc can mutate me. Maybe. You never know who is going to change me! So O you ignorant, stop playing an all-knowing god, and don't dare touch the code where I'm present. Okay?"

Well, that is how volatile prevents the compiler from optimizing code. Now search the web to see some sample examples.


Quoting from the C++ Standard ($7.1.5.1/8)

[..] volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation.[...]

Related topic:

Does making a struct volatile make all its members volatile?

The Room
  • 758
  • 1
  • 9
  • 22
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 94
    It's important to add that `volatile` is a qualifier, similar to `const` (but of course with a different meaning) so you can also declare `volatile` methods that can only be called on `volatile` instances. – ereOn Dec 14 '10 at 09:23
  • 1
    I thought this is what the `extern` keyword is for? – Maxpm Dec 21 '10 at 04:29
  • 2
    @Maxpm : No. `extern` keyword is used for something else. – Nawaz Dec 21 '10 at 06:38
  • 3
    As per your example it seems that the compiler optimizes the code well here, as I guess inside of the while function it is not changing the value of some_int. Can you also explain any scenario where some_int value is getting change? If not then what will be use of volatile in this example? – Vivek Kumar Jul 15 '15 at 23:35
  • 4
    Nice answer, it would be good to mention that in the example, the value of some_int could be changed by another thread or an interrupt routine, as two examples which the code would fail, just for clarification. (@dearvivekkumar - this should answer your comment) – Marcelo Dec 29 '15 at 14:24
  • So, by the fact that the value might be changed from outside the own program, caching the variables content gets also disabled by the usage of ```volatile```? – Florian Loch Jan 06 '16 at 15:59
  • 1
    Not getting it, does it imply that compiler could produce wrong binary executable if a programmer forgets to use "volatile" where he should? Can someone offer a sample code to verify this concept? Thanks. – user180574 Jun 15 '16 at 23:39
  • 5
    @user180574: I dont think anybody has time to come up with a sample code to verify this concept, because that is a difficult task. Note that *absence* of `volatile` doesn't guarantee that the *loading* of a variable will be optimised away. It is just that *presence* of `volatile` **ensures** that it is NOT optimised away, even though it is quite possible without the keyword as well; the difference is that *absence* **doesn't ensure** that. – Nawaz Jun 16 '16 at 04:44
  • 1
    Can a program access the memory of another program? – patzi Jan 26 '18 at 00:25
  • 2
    @patzi yes, a program can access the memory of another program. One example is the OS which can access any memory it desires whether it belongs to it or not. Another example is two programs which access a shared buffer, created by mmap for example. – Galaxy Jul 04 '18 at 16:21
  • 1
    I read somewhere in the past that `volatile` is to ensure that a variable will occupy a memory space and will not optimize away by the compiler. With this meaning, for me, made sense to a lot of possible uses of the effect of `volatile`. I guess, `volatile` now is more improved internally and doesn't always need actual memory space for a variable. Is that so? Please help me clearing this. – acegs Sep 19 '18 at 06:24
  • @acegs: If it does not need actual memory space, where will the *value* get stored? Think in terms of this: `volatile int val = 10;` , then does `&val` point to a valid address? – Nawaz Sep 19 '18 at 09:18
  • @Nawaz, so it's safe to say, even in the current internal implementation of `volatile`, that it ALWAYS gives memory space to the variable? I read several answers and comments in stackoverflow regarding the effect of `volatile` and I was curious and confused why they just say "the compiler don't optimize away" instead of confidently saying "it ensure giving memory space to the variable". So I thought there are something more/alternative internal to the `volatile` other than giving it "memory space" that will still fulfill the "volatility". – acegs Sep 20 '18 at 01:07
  • @Nawaz, yeah, that's what I worry from the 1st comment I made here. For many years, I believe that `volatile` is to ensure that the variable be in a memory space, and THAT helps me alot. But lately, including in this stackoverflow page, I haven't read any that confidently say `volatile` variables WILL occupy memory space, and instead say like: 'the compiler don't optimize away' that made me think: "maybe there's something more now". I hope you get my point, I feel we're on 'different page'. But despite all I had read, I guess I'll still choose the old meaning that I know for `volatile`. – acegs Sep 22 '18 at 11:39
  • 1
    @acegs Providing the semantics required for `volatile` may or may not require ensuring the variable has a space in memory on some particular platform. There's no way to know, for all platforms that have ever or will ever existed, that this was and will always continue to be necessary. Heck, one could imagine a platform that has only CPU registers, just lots and lots of them. – David Schwartz Mar 20 '19 at 14:06
  • volatile is used to fix a lot of issues on systems that do not have coherent memory, such as the PS3, XboxOne, etc. For a full understanding of the Volatile keyword, you must understand what coherent memory is vs non-coherent memory. – Dan Mar 21 '19 at 21:26
  • @patzi "_access the memory of another program_" with `ptrace` or similar, on any OS that supports program debugging. Volatile guarantees that when stopped the execution at a sequence point (you can also use `ptrace` to stop threads), the value of a variable can be examined (it is represented according to the ABI) and even modified. – curiousguy Nov 22 '19 at 22:42
  • Can another thread be "some XYZ that you're not even aware of" too? – Yves Sep 13 '20 at 18:02
  • @Yves: Yes. Could be! – Nawaz Sep 13 '20 at 18:04
  • Is it possible for you to share an example of the following situation: " ...the value of some_int from outside the program which compiler is not aware of, since it can't see it; but it's how you've designed it...."? – Ahmet Mar 11 '21 at 22:06
  • O, thoust should write an enjoyable C++ bible – Patrick Y Jul 19 '21 at 16:45
  • This answer is incorrect. The behaviour change in the example you gave is because of syntax tree optimisation by the translator (not specified by the standard) - Also the standard specifically states that this behaviour is not guaranteed (variables marked volatile will do a load after store). The standard section you quoted has to do with the abstract execution engine, which has a very well defined, set of optimisations that the compiler can do (gcc/clang does not honour the volatile keyword restrictions here and mostly delegates it to the -O flag). – tinkerbeast May 16 '22 at 18:44
  • @tinkerbeast: *"variables marked volatile will do a load after store"*.. which part of the spec says that? – Nawaz May 16 '22 at 19:31
  • @Nawaz What I meant was that variables marked volatile will do a load after a store instead of reusing the value in the register. As for the standard, in C11 section 6.7.3, see clause 7. Initially it states: "Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine, except as modified by the unknown factors mentioned previously" - Which most compilers interpret as doing a load every time. Immediately after this it states that an access to a volatile is implementation defined (So your interpretation might differ). – tinkerbeast May 17 '22 at 18:58
  • @tinkerbeast: I don't get your argument against this answer. I also find it difficult to relate what you saying with the text you're quoting from the spec. Can you please elaborate? Or maybe post an answer? Or a gist on github and post the link here? – Nawaz Jun 05 '22 at 14:09
  • How does it help that you stop the compiler from performing certain optimizations when those very same optimizations could be performed by the CPU, the memory controller, the operating system, system libraries, drivers, or any other component of the system? Since `volatile` doesn't guarantee any particular effect from preventing the compiler from performing optimizations, what use is it except on specific platforms that provide actual guarantees? – David Schwartz Aug 01 '23 at 14:45
32

In computer programming, particularly in the C, C++, and C# programming languages, a variable or object declared with the volatile keyword usually has special properties related to optimization and/or threading. Generally speaking, the volatile keyword is intended to prevent the (pseudo)compiler from applying any optimizations on the code that assume values of variables cannot change "on their own." (c) Wikipedia

http://en.wikipedia.org/wiki/Volatile_variable

jrbedard
  • 3,662
  • 5
  • 30
  • 34
Ivan
  • 3,567
  • 17
  • 25
  • 44
    volatile has nothing to do with threads – BЈовић Dec 14 '10 at 10:13
  • 46
    The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread. (c) MSDN C++ Reference. (http://msdn.microsoft.com/en-us/library/12a04hfd(v=vs.80).aspx) But certainly msdn and wikipedia are wrong, and you are correct. – Ivan Dec 14 '10 at 10:54
  • 17
    `volatile` doesn't help with threading though. Volatile reads/writes can still be reordered with respect to non-volatile ones, which makes it useless for threading purposes. Also, you may have noticed the big fat "Microsoft Specific" on the MSDN page. Microsoft's implementation of volatile provides additional guarantees beyond those specified by the standard. So yes, technically speaking, MSDN is wrong. And it should be little surprise that Wikipedia can be wrong. – jalf Dec 21 '10 at 09:41
  • 14
    It is true though that the properties of `volatile` are *related to* threading. Using `volatile` on a variable shared between threads can change the semantics of your program. `volatile` just isn't strong enough to change the semantics to anything *useful* or well-defined. – jalf Dec 21 '10 at 11:28
  • 5
    I'm afraid you dont know what you are talking about @jalf . the volatile keyword grantees that changes to a variable in one thread, remains coherent across all threads. By inserting fences, barriers, cache flushes, reloads, etc as needed for that platform. if you did anything but pc development you might know this. Just because intel hides a lot of cache management from you does not mean it isn't happening. – Dan Mar 21 '19 at 21:30
  • 3
    In Java, [`volatile` is indeed related to threading](https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html), I believe it has similar implications in C++ and C#. – jjmontes May 15 '19 at 20:42
  • @jalf but it does... for example, situations where you care about memory being up to date but not exactly: a cache flush mechanism that reads a "last_update" variable, updated by some other thread. You don't care if a cache is flushed some milliseconds later, but you need to have "something close to truth" (remember that, in some languages likeJava, without volatile, seconds or minutes can pass before a thread sees a change done by other thread). – jjmontes May 15 '19 at 22:30
  • @BЈовић The possible uses of volatile for inter thread communication are few and not very powerful, but volatile is fine in these restricted case. Atomic variables are better, but volatile is OK. – curiousguy Nov 22 '19 at 22:44
  • @Dan "_I'm afraid you dont know what you are talking about_" Actually you are the one with zero idea what you are talking about; which compiler on which system for which language inserts a cache flush for which operation? – curiousguy Nov 22 '19 at 22:47
  • @curiousguy I didn't mean a cache flush was involved, rather that fencing or memory management techniques are in place. In Java, the Memory Model ensures that all threads see a consistent value for the variable, preventing other threads from reading old values (presumably cached). In C++, this is platform dependent but [some arquitectures apparently introduce fences](https://stackoverflow.com/questions/26307071/does-the-c-volatile-keyword-introduce-a-memory-fence), you're right seems it's indeed unrelated to multithreading. In C#, again, volatile is related to multiprocessing. – jjmontes Nov 23 '19 at 00:51
  • 2
    @jjmontes Indeed in Java `volatile` is a communicating tool for threads and writes to these scalars have a specific meaning. **In C and C++, `volatile` is primarily a tool for MMIO** (extension cards, drivers...), async signals, the special pseudo function `setjmp`, and has a other uses unrelated w/ threads. Standard support for inter thread communication in C and C++ is via atomic objects (spelled `std::atomic` in C++). Their semantics are totally different. – curiousguy Nov 23 '19 at 00:57
  • @curiosguy by "clearing a cache" I was meaning an example like when you use volatile variables (Java / C#) to store the "last updated time" of a value in a memory cache (for example a LRU memory cache). When clearing that cache, it's not a big deal to evict an object just because you are reading a slightly outdated value, since the value will be loaded again. But you avoid locking each time you need to check if the value is still valid. It's a toy example, but my point is that I wasn't referring to "CPU cache flush" at all. A more typical usage is for managing the exit condition of a loop. – jjmontes Nov 23 '19 at 00:58
  • @jjmontes How do you do any of that? By which instructions? – curiousguy Nov 23 '19 at 16:48
  • 2
    @curiousguy this is a C++ question and my comment was about Java and C# (once it's been shown I was wrong about C++), so we should not pollute this thread. Anyway: for Java, read [this](https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html) and [this](https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html) and this is a classic example: https://stackoverflow.com/questions/11595868/while-loop-not-ending-when-flag-changed-in-different-thread . For C# , use Google ;-) – jjmontes Nov 23 '19 at 18:17