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.
GCC compiler makes an assumption that pointers of different types will never point to the same memory location i.e., alias of each other. Strict aliasing rule helps the compiler to optimize the code.
Pointer aliasing is a hidden kind of data dependency that can occur in C, C++, or any other language that uses pointers for array addresses in arithmetic operations. Array data identified by pointers in C can overlap, because the C language puts very few restrictions on pointers.
An alias occurs when different variables point directly or indirectly to a single area of storage. Aliasing refers to assumptions made during optimization about which variables can point to or occupy the same storage area.
Because any pointer could alias any other pointer in C, the compiler must assume that memory regions accessed through these pointers can overlap, which prevents many possible optimizations. C++ enables more optimizations, as pointer arguments will not be treated as possible aliases if they point to different types.
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.
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