gcc: Volatiles

1 
1 6.44 When is a Volatile Object Accessed?
1 ========================================
1 
1 C has the concept of volatile objects.  These are normally accessed by
1 pointers and used for accessing hardware or inter-thread communication.
1 The standard encourages compilers to refrain from optimizations
1 concerning accesses to volatile objects, but leaves it implementation
1 defined as to what constitutes a volatile access.  The minimum
1 requirement is that at a sequence point all previous accesses to
1 volatile objects have stabilized and no subsequent accesses have
1 occurred.  Thus an implementation is free to reorder and combine
1 volatile accesses that occur between sequence points, but cannot do so
1 for accesses across a sequence point.  The use of volatile does not
1 allow you to violate the restriction on updating objects multiple times
1 between two sequence points.
1 
1  Accesses to non-volatile objects are not ordered with respect to
1 volatile accesses.  You cannot use a volatile object as a memory barrier
1 to order a sequence of writes to non-volatile memory.  For instance:
1 
1      int *ptr = SOMETHING;
1      volatile int vobj;
1      *ptr = SOMETHING;
1      vobj = 1;
1 
1 Unless *PTR and VOBJ can be aliased, it is not guaranteed that the write
1 to *PTR occurs by the time the update of VOBJ happens.  If you need this
1 guarantee, you must use a stronger memory barrier such as:
1 
1      int *ptr = SOMETHING;
1      volatile int vobj;
1      *ptr = SOMETHING;
1      asm volatile ("" : : : "memory");
1      vobj = 1;
1 
1  A scalar volatile object is read when it is accessed in a void context:
1 
1      volatile int *src = SOMEVALUE;
1      *src;
1 
1  Such expressions are rvalues, and GCC implements this as a read of the
1 volatile object being pointed to.
1 
1  Assignments are also expressions and have an rvalue.  However when
1 assigning to a scalar volatile, the volatile object is not reread,
1 regardless of whether the assignment expression's rvalue is used or not.
1 If the assignment's rvalue is used, the value is that assigned to the
1 volatile object.  For instance, there is no read of VOBJ in all the
1 following cases:
1 
1      int obj;
1      volatile int vobj;
1      vobj = SOMETHING;
1      obj = vobj = SOMETHING;
1      obj ? vobj = ONETHING : vobj = ANOTHERTHING;
1      obj = (SOMETHING, vobj = ANOTHERTHING);
1 
1  If you need to read the volatile object after an assignment has
1 occurred, you must use a separate expression with an intervening
1 sequence point.
1 
1  As bit-fields are not individually addressable, volatile bit-fields may
1 be implicitly read when written to, or when adjacent bit-fields are
1 accessed.  Bit-field operations may be optimized such that adjacent
1 bit-fields are only partially accessed, if they straddle a storage unit
1 boundary.  For these reasons it is unwise to use volatile bit-fields to
1 access hardware.
1