c/language/volatile

Each individual type in the C has several qualified versions of that type, corresponding to one, two, or all three of the, volatile, and, for pointers to object types,  qualifiers. This page describes the effects of the volatile qualifier.

Every access (both read and write) made through an lvalue expression of volatile-qualified type is considered an observable side effect for the purpose of optimization and is evaluated strictly according to the rules of the abstract machine (that is, all writes are completed at some time before the next sequence point). This means that within a single thread of execution, a volatile access cannot be optimized out or reordered relative to another visible side effect that is separated by a from the volatile access.

A cast of a non-volatile value to a volatile type has no effect. To access a non-volatile object using volatile semantics, its address must be cast to a pointer-to-volatile and then the access must be made through that pointer.

Any attempt to read or write to an object whose type is volatile-qualified through a non-volatile lvalue results in undefined behavior:

A member of a volatile-qualified structure or union type acquires the qualification of the type it belongs to (both when accessed using the operator or the  operator):

If a function type is declared with the volatile type qualified (through the use of ), the behavior is undefined.

A pointer to a non-volatile type can be implicitly converted to a pointer to the volatile-qualified version of the same or. The reverse conversion can be performed with a cast expression.

Note that pointer to pointer to is not convertible to pointer to pointer to ; for two types to be compatible, their qualifications must be identical:

Uses of volatile
@1@  objects model memory-mapped I/O ports, and    objects model memory-mapped input ports, such as a real-time clock:

@2@  objects of type sig_atomic_t are used for communication with signal handlers. @3@ variables that are local to a function that contains an invocation of the setjmp macro are the only local variables guaranteed to retain their values after longjmp returns. @4@ In addition, volatile variables can be used to disable certain forms of optimization, e.g. to disable dead store elimination or constant folding for micro-benchmarks.

Note that volatile variables are not suitable for communication between threads; they do not offer atomicity, synchronization, or memory ordering. A read from a volatile variable that is modified by another thread without synchronization or concurrent modification from two unsynchronized threads is undefined behavior due to a data race.