------- Additional Comments From hugh at mimosa dot com 2005-07-16 16:18 ------- Here is some C Lawyering from Henry Spencer. I asked him to look at and comment on this bug. With his permission, I'm quoting his response here.
There is little room for compiler writers to maneuver here, unless they have announced their intentions in advance in their documentation. Reading C99 carefully: 6.5.3.2: applying `*' to a pointer of type `T *' which points to an object yields an lvalue of type `T' designating that object. So the lvalue in the assignment has a volatile-qualified type. 6.3.2.1: when an object is said to have a particular type, the type is specified by the lvalue used to designate the object. So the lvalue having a volatile-qualified type *means* that the object it designates has a volatile-qualified type; "has type X" and "is designated by an lvalue of type X" are synonymous (!). 6.7.3: any expression referring to an object of volatile-qualified type must be evaluated strictly by the rules of the abstract machine, although precisely what constitutes an "access" to the object is implementation-defined. (Note, "implementation-defined" behavior is required to be well-defined and *documented*.) So if the reference in question is an "access", it must occur where the abstract machine says it should. 5.1.2.3: the abstract machine evaluates all expressions as specified by semantics and all side effects must occur, side effects including "accessing a volatile object"; implementations are allowed to skip part of expression evaluation only if they can deduce that no needed side effects (notably "accessing a volatile object") are therefore skipped. So if the reference is an "access", it must occur, period. I see no useful wiggle room in the difference between "access" and "accessing", or the difference between "volatile object" and "object of volatile-qualified type". These appear to me to be minor accidents of inconsistent terminology, not useful to a sane implementer. 6.7.3 says that to refer to an object "defined with" volatile-qualified type "through use of an lvalue" with non-volatile-qualified type yields undefined behavior. However, the reference here uses a volatile-qualified lvalue, so this is not relevant. A pointer value is not an lvalue; there is no lvalue present until the `*' operator is applied. Surprising though it might seem, I see no express or implied permission to distinguish based on whether the object in question was *defined* with a volatile-qualified type. There are places in the standard where how an object is defined is significant, e.g. the rules for `const' and the part of 6.7.3 noted in the previous paragraph, but none of them is part of the chain of reasoning above. The only loophole is the definition of "access". If GCC wishes to claim standard conformance, GCC is required to document its definition. I'm not aware of any mention of this in the GCC documentation, although I haven't dug hard for it. I see no room for a reasonable definition of "access" which retains some useful meaning for `volatile' and doesn't cover the reference in question. (I agree that you can contrive a definition which contains special-case wording to cover this case, but not that it's reasonable to do so.) If GCC (a) wants to be C99-conforming, and (b) wants to provide useful semantics for `volatile', this is a bug. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22278