GNU Info

Info Node: (gcc-300.info)Volatiles

(gcc-300.info)Volatiles


Next: Restricted Pointers Prev: Min and Max Up: C++ Extensions
Enter node , (file) or (file)node

When is a Volatile Object Accessed?
===================================

   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.  The C++ standard specifies that such expressions do not undergo
lvalue to rvalue conversion, and that the type of the dereferenced
object may be incomplete.  The C++ standard does not specify explicitly
that it is this lvalue to rvalue conversion which is responsible for
causing an access.  However, there is reason to believe that it is,
because otherwise certain simple expressions become undefined.  However,
because it would surprise most programmers, G++ treats dereferencing a
pointer to volatile object of complete type in a void context as a read
of the object.  When the object has incomplete type, G++ issues a
warning.

     struct S;
     struct T {int m;};
     volatile S *ptr1 = SOMEVALUE;
     volatile T *ptr2 = SOMEVALUE;
     *ptr1;
     *ptr2;

   In this example, a warning is issued for `*ptr1', and `*ptr2' causes
a read of the object pointed to.  If you wish to force an error on the
first case, you must force a conversion to rvalue with, for instance a
static cast, `static_cast<S>(*ptr1)'.

   When using a reference to volatile, G++ does not treat equivalent
expressions as accesses to volatiles, but instead issues a warning that
no volatile is accessed.  The rationale for this is that otherwise it
becomes difficult to determine where volatile access occur, and not
possible to ignore the return value from functions returning volatile
references.  Again, if you wish to force a read, cast the reference to
an rvalue.


automatically generated by info2www version 1.2.2.9