Such an object is normally accessed by pointers and used for accessing hardware. In most expressions, it is intuitively obvious what is a read and what is a write. For example
volatile int *dst = somevalue ; volatile int *src = someothervalue ; *dst = *src;
will cause a read of the volatile object pointed to by src
and store 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
However, if the volatile storage is not being modified, and the value of the volatile storage is not used, then the situation is less obvious. For example
volatile int *src = somevalue ; *src;
According to the C standard, such an expression is an rvalue whose type is the unqualified version of its original type, i.e.
. Whether GCC interprets this as a read of the volatile object being pointed to or only as a request to evaluate the expression for its side-effects depends on this type.
If it is a scalar type, or on most targets an aggregate type whose only member object is of a scalar type, or a union type whose member objects are of scalar types, the expression is interpreted by GCC as a read of the volatile object; in the other cases, the expression is only evaluated for its side-effects.