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.
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.