In computer programming in the C and C++ programming languages, a variable or object declared with the volatile keyword may be modified externally from the declaring object. Variables declared to be volatile will not be optimized by the compiler because the compiler must assume that their values can change at any time. Note that operations on a volatile variable are still not guaranteed to be atomic.
What can happen if volatile is not used?
The following pieces of C source code demonstrate the use of the volatile
keyword.
static int foo;
void bar(void)
{
foo = 0;
while (foo != 255)
;
}
In this example, the code sets the value stored in foo
to 0. It then starts to poll that value repeatedly until it changes to 255.
An optimizing compiler will notice that no other code can possibly change the value stored in foo
, and therefore assume that it will remain equal to 0 at all times. The compiler will then replace the function body with an infinite loop, similar to this:
void bar_optimized(void)
{
foo = 0;
while (true)
;
}
However, foo
might represent a ___location that can be changed by other elements of the computer system. It could be a hardware register of a device connected to the CPU. The value stored there could change at any time. The above code would never detect such a change; without the volatile
keyword, the compiler assumes the current program is the only part of the system that could cause the value to change. (This is by far the most common situation.)
To prevent the compiler from modifying code in this way, the volatile
keyword is used in the following manner:
static volatile int foo;
void bar(void)
{
foo = 0;
while (foo != 255)
;
}
With this modification the loop condition will not be optimized away, and the CPU will detect the change when it occurs.
For an example of the use of volatile
in context, see Busy waiting.
Note that using volatile as a threading primitive is not guaranteed to work in C, C++, or Java versions 1 to 1.4. There are many systems where it will not. In C, and consequently C++, volatile was intended to allow access to memory mapped devices. Volatile was not intended, and it not implemented on all systems, to be a correct or useful synchronization primitive.