In some ways, this is kind of the core observation of Rust: "shared xor mutable". Aliasing is only an issue if the aliasing leads to mutability. You can frame it in terms of aliasing if you have to assume all aliases can mutate, but if they can't, then that changes things.
Nevertheless, I don't write normal everyday C code anymore since Rust has pretty much made it completely obsolete for the type of software I write.
If you do not use that the generated code can be quite suboptimal in certain cases.
> If you do not use that the generated code can be quite suboptimal in certain cases.
I believe you, but I don't understand it. Can you give a simple example to demonstrate your point?Note that memcpy specifically may already be implemented this way under the hood because it requires noalias; but I imagine similar iterative copying operations can be optimized in a like manner ad-hoc when aliasing information is baked in like it is with Rust.
The real purpose of restrict is to allow the compiler to cache a value that may be used many times in a loop (in memcpy(), each byte/word is used only once) in a register at the start of the loop, and not have to worry about repeatedly reaching back to memory to re-retrieve it because it might have been modified as a side effect of the loop body.
You then write access the second pointer. Now the value you kept in the register is invalidated since you might have overwritten it through the overlapping pointers.
This does come with code-bloat. So the Rust std sometimes exposes a generic function (which gets monomorphized), but internally passes it off to a non-generic function.
This to avoid that the underlying code gets monomorphized.
https://github.com/rust-lang/rust/blob/8c52f735abd1af9a73941...
There's no free lunch here. Reducing the amount of code that's monomorphised reduces the code emitted & improves compile times, but it reduces the scope of the code that's exposed to the input type, which reduces optimisation opportunities.
In C, the only way to write a monomorphized hash table or array list involves horribly ugly macros that are difficult to write and debug. Rust does monomorphization by default, but you can also use &dyn trait for vtable-like behaviour if you prefer.