When the compiler can assume your values don't change magically, it can optimize their use.
This is true for restricted pointers, for global-scope variables which can only be accessed in the same translation unit, for stuff in inlined functions (often), etc.
--------------------------------------------
const is a bit shifty. const makes the compiler restrict what it allows you to write, but it can still not really assume other functions don't break constness via casting:
void i_can_change_x_yeah_i_can_just_watch_me(const int* x)
{
*(int*) x = x + 1;
}
now, if the compiler sees the code, then fine (maybe), but when all you see is:
Specifically it's well-defined behavior to mutate an object after const_cast-ing away constness if the object wasn't const to begin with (const references or const pointers can refer to non-const objects).
In your first example you have `int x = 1;` which isn't const, so the compiler has to assume that `f` may mutate it after const casting.
In your second example you have `const int x = 1;` which is const so the compiler can assume the value will never change.
I believe this account of things is accurate (ignoring C++'s reference types for simplicity):
The C and C++ standards are written in such a way as to enable compilers to place constant data on read-only memory. Casting away constness is never illegal in and of itself, but if you do so and then assign to a variable which was declared as const, that is undefined behaviour.
Similarly, assigning into the character array of a string literal is undefined behaviour, whether or not const was used. Again that's to enable the compiler to make use of read-only memory.
Going in the other direction is safe, as preventing assignments doesn't introduce problems. That is to say, using a pointer-to-const type to point to a non-const variable poses no problem.
When the compiler can assume your values don't change magically, it can optimize their use.
This is true for restricted pointers, for global-scope variables which can only be accessed in the same translation unit, for stuff in inlined functions (often), etc.
--------------------------------------------
const is a bit shifty. const makes the compiler restrict what it allows you to write, but it can still not really assume other functions don't break constness via casting:
now, if the compiler sees the code, then fine (maybe), but when all you see is: You can't assume the value pointed to by x can change. See this on GodBolt: https://godbolt.org/z/fGEMj9Meoand it could well be the same for constants too. But somehow it isn't:
https://godbolt.org/z/fqGzh7o8z