The rust undefined behaviour rules are stricter than C: mutating a non mutable reference is UB, for example. Non mutable references don't exist in C.
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.
(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.)
const int x = 123;
const int *px = &x;
(*(int*)px) = 456;
is very, very UB in C (and most likely will crash on most platforms) 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.