In rust you can createRust, creating a raw pointer safelyis allowed in safe code (i.e. outside of unsafe
blocks), but then dereferencing it is unsafe:
let my_num_ptr: *const i32 = &my_num;
But then dereferencing it is unsafe:
let value: i32 = unsafe {*my_num};
To cause undefined behavior requiresUndefined behaviour would only occur in a program which both constructingcreates and incorrectly dereferences a invalidraw pointer then de-referencing it. AsSo long as one partof these operations is unsafe it should be impossible to read bad memory in only safe codeallowed in an unsafe
block, memory safety can be guaranteed for programs which have no unsafe
blocks.
So something likeWhat if, instead of requiring an unsafe
block for the dereference operation, it is instead required for the creation of the raw pointer? For example:
let i: const *u32 = unsafe {
&4
};
let b=*i;b = *i;
Or even:
let i: mut *u32 = unsafe {
&mut &8;
8};
*i=5;*i = 5;
Other pointerIn this hypothetical language, operations like casting would also becomewhich create a raw pointer are unsafe (and must only occur in unsafe
blocks), but dereferencing them is allowed in safe code, on the basis that it's the programmer's responsibility to make sure when creating the raw pointer that the pointed-to value will stay alive at that memory address for long enough. Is this sound? Would there be any advantages to doing it this way instead of the rustRust way.?
Note that in rustRust, a unsafe block does not mean that the entire program is unsafe. Just, just that there are invariantinvariants the compiler can't check and, so the programmer is responsible for them. If the programmer has made sure the rules are followed, it's perfectly safe.
In rustRust currently, it is undefined behavior to dereference a null pointer, a unaligned pointer, or one that points to uninitialized memory. I'm suggesting that instead the undefined behavior happens when contstructingconstructing such a pointer instead.