[Filing this as gcc 4.4.4 since that is the version of the docs I'm looking at, however, we care about behavior from gcc 3.4 and onward.]
A major disagreement has developed inside the Linux kernel community about the semantics that gcc imposes on "volatile". One school of thought states that volatile operations (both volatile memory references and "asm volatile") are equivalent to device I/O and therefore:
a) will be issued exactly once per programmatic execution;
b) will not be reordered with respect to each other (as opposed to with respect to nonvolatile operations).
We have relied pretty hard on these two properties in the Linux kernel, but the documentation makes it unclear if this is indeed the intended semantics. It would be good if this could be clarified and documented. Since this is affecting current Linux kernel code, we would appreciate a formal reply as quickly as possible.
The examples in the documentation are all volatile vs. non-volatile. We are clear on the fact that volatiles can be reordered with respect to nonvolatiles, except that "asm volatile" takes all of memory as an implicit input, and obviously "memory" clobbers are used to make all of memory an implicit output.
I believe the following statement in the documentation does, indeed, provide the guarantee we need, but we would like to make it explicit, especially since (a) it is found in a section about C++, and (b) it technically refers to the C/C++ standards, and "asm" is inherently non-standard.
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. 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.
Your help in authoritatively clarifying the situation would be most appreciated.