3.10/10 says:
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
However, the term "access" is not defined anywhere. In this context does it mean read, or read or modify ?
In the C standard it is unambiguously defined as read or modify. However in C++11 it seems to be used with different meanings at different times, for example:
1.9/8:
Access to volatile objects are evaluated strictly according to the rules of the abstract machine.
Clearly this is meant to be read or modify, however in many other places such as 1.10/24:
- access or modify a volatile object, or
it is used as if it only means read.
It must mean both read and write, or the rule wouldn't mean much. Consider the example from http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html:
float *P;
void zero_array() {
int i;
for (i = 0; i < 10000; ++i)
P[i] = 0.0f;
}
The example code above can be optimized into a memset
only if the compiler can assume that none of P[i]
aliases P
. But consider a world in which only reading from an disallowed glvalue is UB, then the above code would not invoke UB even if P[i]
aliases P
for some i
- e.g., if someone did P = (float *) &P;
, because all reads of P
are perfectly legal - they all use the lvalue expression P
.
Edit: CWG issue 1531 is directly on point. The issue was moved to DR (defect report) status in April 2013, but the resolution, for whatever reason, wasn't applied to the working paper.
I don't claim to be a language lawyer. However...
I would interpret the phrase "access the stored value of an object" as "read the stored value of an object".
That interpretation makes more sense given the previous paragraph, which talks about modifying an object.
9 If an expression can be used to modify the object to which it refers, the expression is called modifiable. A program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is ill-formed.