A non const pointer to an array element can be used to access the entire array, which would require the compiler to reload any previously fetched array elements from memory:
void use_value(int* a) {
a[1] = 2; // change array pointed to by a
}
void do_thing() {
int a[] = {1, 2, 3};
calculate(a[1]); // do something with this value (presumably a[1] will be stored in a register)
use_value(&a[0]);
calculate(a[1]); // the compiler must now reload a[1] from memory
}
What I'm wondering is whether this issue occurs if the pointer is changed to a reference:
void use_value(int& a) {
(&a)[1] = 2; // is this UB?
}
void do_thing() {
int a[] = {1, 2, 3};
calculate(a[1]); // do something with this value (presumably a[1] will be stored in a register)
use_value(a[0]);
calculate(a[1]); // must the compiler now reload a[1] from memory?
}
Binding a reference to an object and then using it to obtain a pointer to that object produces the same pointer value as doing so without the reference, so arithmetic definitely applies. All elements of an array (but not the array itself) alias together as a result.
The standard doesn’t define anything to make this happen (it’s just another pointer to the object), but it acknowledges this situation (in bounding the power of std::launder
) by defining when a byte of memory is reachable through a pointer value ([basic.compound]/6).