|
||||
|
Section 18:
|
[18.15] Why does the compiler allow me to change an int after I've pointed at it with a int const*?
Because "int const* p" means "p promises not to change the *p," not "*p promises not to change." Causing a int const* to point to an int doesn't const-ify the int. The int can't be changed via the int const*, but if someone else has an int* (note: no const) that points to ("aliases") the same int, then that int* can be used to change the int. For example:
void f(int const* p1, int* p2)
{
int i = *p1; // Get the (original) value of *p1
*p2 = 7; // If p1 == p2, this will also change *p1
int j = *p1; // Get the (possibly new) value of *p1
if (i != j) {
std::cout << "*p1 changed, but it didn't change via pointer p1!\n";
assert(p1 == p2); // This is the only way *p1 could be different
}
}
int main()
{
int x = 5;
f(&x, &x); // This is perfectly legal (and even moral!)
...
}
Note that main() and f(int const*,int*) could be in different
compilation units that are compiled on different days of the week. In that
case there is no way the compiler can possibly detect the aliasing at compile
time. Therefore there is no way we could make a language rule that prohibits
this sort of thing. In fact, we wouldn't even want to make such a rule, since
in general it's considered a feature that you can have many pointers pointing
to the same thing. The fact that one of those pointers promises not to change
the underlying "thing" is just a promise made by the pointer; it's
not a promise made by the "thing".
|
|||