 |
Definite Access of Volatile Objects |
Both the C and C++ standard have the concept of volatile objects. These
are normally accessed by pointers and used for accessing hardware. The
standards encourage compilers to refrain from optimizations
concerning accesses to volatile objects that it might perform on
non-volatile objects. The C standard leaves it implementation defined
as to what constitutes a volatile access. The C++ standard omits to
specify this, except to say that C++ should behave in a similar manner
to C with respect to volatiles, where possible. The minimum either
standard specifies is that at a sequence point all previous accesses to
volatile objects have stabilized and no subsequent accesses have
occurred. Thus an implementation is free to reorder and combine
volatile accesses which occur between sequence points, but cannot do so
for accesses across a sequence point. The use of volatiles does not
allow you to violate the restriction on updating objects multiple times
within a sequence point.
In most expressions, it is intuitively obvious what is a read and what is
a write. For instance
volatile int *dst = somevalue;
volatile int *src = someothervalue;
*dst = *src;
will cause a read of the volatile object pointed to by src and stores the
value into the volatile object pointed to by dst. There is no
guarantee that these reads and writes are atomic, especially for objects
larger than int
.
Less obvious expressions are where something which looks like an access
is used in a void context. An example would be,
volatile int *src = somevalue;
*src;
With C, such expressions are rvalues, and as rvalues cause a read of
the object, GCC interprets this as a read of the volatile being pointed
to.