When working through const
declarations, you look backwards. Unfortunately it has one exception: const int
is allowed for historical reasons, but it means the same as int const
.
Below, the const
"looks back" to the int
so p
points to an int which can't be changed.
int const * p;
And here, the const
"looks back" to the int *
so p
is not allowed to point to anything else, but what it points to now can be changed through p
.
int i = 5; int j = 5;
int * const p = &i;
*p = 6; // ok, you can still modify `i` through `p`
p = &j; // error because you can't change what `p` points at
And here, p
is a const pointer to a const int. p
is not allowed to change and what it points to cannot be changed.
int i = 5; int j = 5
int const * const p = &i;
*p = 6; // error, promised not to makes changes through `p`
p = &j; // error `p` is stuck to `i`
When assigning one thing to another, the rule is that promises cannot be broken. int const
is a promise that the int
will never be changed. If you try this:
int const i = 5;
int * p = &i; // error
and the compiler let you do it, you would then be able to break the promise that i
would never change by doing this
*p = 6;
and now i
will be changed from 5 to 6, breaking the promise that i
will never change.
It's ok the other way round because you're not breaking any promises. In this case, you're only promising not to change i
when you access it through the pointer p
int i = 5;
int const * p = &i;
*p = 6; // error, because we promised not to change `i` through `p`
i = 6; // ok, because `i` itself is not const
const
is important as a built-in safety check. The compiler will give you an error if something you declare as const
is changed. You can declare methods of a class to be const
and that is a promise that no data in the class will be changed by that method. It's easy to forget and later modify that method to change something in the class but the compiler will remind you.
It is also important for optimisation. If the compiler knows that something is const
it can make a lot of simplifying assumptions to speed up the code.