The standard is quite pedantic in defining any terms used in its text. For example, the term "access" is defined in the context dictionary at the beginning of the standard as modifying or reading the value of an object. For volatile objects, section 5.1.2.3 defines volatile access:
"An access to an object through the use of an lvalue of volatile-qualified type is a volatile access."
However, when reading section 6.7.3 7 on type qualifiers, I come across some "refer to" expression in relation to a volatile object:
"If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.161)"
I am not a native English speaker, and it is difficult for me to understand whether there is a special meaning in this, or whether this is an omission by the authors of the Standard, since in this case it would be quite appropriate to specify the specific term "access". That is, it would be correct to write:
"If an attempt is made to access to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.161)"
Otherwise, the phrase "refer to" should be taken quite literally. Then any calculation of the address of a volatile object in a pointer that does not have such a qualifier for the type being pointed to (even if such an object is not accessed) is undefined behavior, according to the quoted line of the standard. Please clarify.
I think this is likely just sloppy language. Looking through C 2024, there are very few uses of “refer” (in any form, like “reference” or “referring”) in regard to an expression using an object. One is in footnote 152, about restrict: “… value of an object referenced indirectly through P…” Here the additional text, “value of…”, tells us an expression is indeed accessing an object to get its value, and the object has been “referenced” through something. So the language is a bit slippery.
Another is in 6.2.4: “If an object is referred to outside of its lifetime, the behavior is undefined.” This one is less clear; the text could be talking about just taking the address of an object, not accessing it. The next sentence says “If a pointer value is used in an evaluation after the object the pointer points to (or just past) reaches the end of its lifetime, the behavior is undefined,” and that is definitely just about using the address of an object outside of its lifetime, not accessing the object.
Given the lack of clarity, we have to ask what makes sense. What makes volatile objects special is the object “can be modified in ways unknown to the implementation or have other unknown side effects” (6.7.4). The latter is also unfortunate language. It does not say that accessing the object can have unknown side effects but that the object can have unknown side effects. Taken literally, that could mean the object is emitting radiation that spontaneously might change processor registers, even if the object is not accessed.
But we know that is not the meaning of “volatile.” We know the meaning is that accessing the object can have unknown side effects. For example, setting bits in a special control register might trigger some external device. We know this means that every read from the object in the abstract machine must be implemented as a physical read in the computer so that those side effects are triggered, and similarly that every write to the object in the abstract machine must be implemented as a physical write in the computer.
It would not make sense that every determination of the lvalue of a volatile (effectively, computing its address) must be implemented in the physical computer, as there is nothing special about computing the address of a volatile object. That operation is not expected to have side effects, so it is not special and is not part of what volatile requires.
In conclusion, this use of “refer to” is imprecise, and the text likely should have used “access”: If an attempt is made to access an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With