It is a misconception that the volatile
qualifier provides the following desired properties necessary for a multithreaded program:
- Atomicity: Indivisible memory operations.
- Visibility: The effects of a write action by a thread are visible to other threads.
- Ordering: Sequences of memory operations by a thread are guaranteed to be seen in the same order by other threads.
Unfortunately, the volatile
qualifier does not provide guarantees for any of these properties, neither by definition nor by the way it is implemented in various platforms. For more information on how volatile
is implemented, consult DCL17-C. Beware of miscompiled volatile-qualified variables.
The C Standard, section 5.1.2.3, paragraph 2 [ISO/IEC 9899:2011], says
...
In a nutshell, all this keyword does is inform the compiler that this variable may change in ways that cannot be determined; therefore, the compiler should not perform optimizations in memory areas marked as volatile. In other wordsFor example, the compiler should not store the value in a register and use the register instead of doing accessing expensive memory accessesdirectly. This concept is closely related to multithreading because if a shared variable is cached, a thread may change it, and the other threads may consequently read stale data.
This property of the volatile
keyword is sometimes misunderstood to provide atomicity of a variable that is shared between threads in a multithreaded program. A variable declared as volatile
is not cached in a register, leading to this confusion that it can be used safely as a synchronization primitive. When a variable is declared volatile
, the compiler does not reorder the sequence of reads and writes to that memory location. However, the compiler might reorder these reads and writes with those to other memory locations. This might result in nonatomic operations on the synchronization variable, causing errors. Do not assume that the volatile
qualifier provides any of the following desired properties necessary for a multithreaded program:
- Atomicity: Indivisible memory operations.
- Visibility: The effects of a write action by a thread are visible to other threads.
- Ordering: Sequences of memory operations by a thread are guaranteed to be seen in the same order by other threads.
The volatile
qualifier provides no guarantees for any of these properties, either by definition or by the way it is implemented in various platforms. For more information on how volatile
is implemented, consult DCL17-C. Beware of miscompiled volatile-qualified variables.
Noncompliant Code Example
...