Sure they do: C has a well-defined notion of const-correctness. If you mutate through a `const`, you're invoking undefined behavior.
Both C and C++ allow you to strip `const` from a const-qualified value or reference, but only under the condition that you don't actually modify that value.
Edit: which, in case it isn't clear, means that Rust's UB is exactly the same as C's in this case.
Actually in C++ you are allowed to strip const and modify the value as long as the original object (not necessarily object in an OO sense) isn't const [1].
Yes: the implication was that the original object was `const`. If you both add and remove const, that's well-defined.
(I've yet to see a C or C++ codebase where object provenance actually guarantees this; I've see a lot of C and C++ codebases with const-stripping induced UB.)
C and Rust don't have more strict rules than each other; each has some things that the other disallows, and doesn't allow some things the other allows. It's not that simple.
Rust has raw pointers and UnsafeCell, but they're quite unidiomatic compared to the C/C++ equivalent. A lot of Rust library code only takes safe references so it's hard to use from an unsafe context.
int x = 123;
const int *px = &x;
(*(int*)px) = 456;
is legal in C. The Rust equivalent using & and &mut is UB. Writing this in Rust using raw pointers requires unsafe blocks everywhere, loses method syntax, has no -> operator, etc.
Sure they do: C has a well-defined notion of const-correctness. If you mutate through a `const`, you're invoking undefined behavior.
Both C and C++ allow you to strip `const` from a const-qualified value or reference, but only under the condition that you don't actually modify that value.
Edit: which, in case it isn't clear, means that Rust's UB is exactly the same as C's in this case.