Skip to content

Commit b794f8a

Browse files
committed
Expand on pointer<->address casts without mentioning provenance.
1 parent f41e1a8 commit b794f8a

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

src/expressions/operator-expr.md

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -380,20 +380,34 @@ Casts an enum to its discriminant, then uses a numeric cast if needed.
380380

381381
#### Pointer to address cast
382382

383-
Casting from a valid raw pointer to `usize` will produce the address that is pointed to.
384-
385-
The pointer's provenance is lost in this conversion.
383+
Casting from a raw pointer to an integer produces the machine address of the referenced memory.
384+
If the integer type is smaller than the pointer type, the address may be truncated; using `usize` avoids this.
386385

387386
#### Address to pointer cast
388387

389-
Casting from `usize` to a raw pointer will produce a raw pointer to the same location as the original pointer, if the `usize` was obtained through a pointer to address cast of a valid pointer.
388+
Casting from an integer to a raw pointer interprets the integer as a memory address and produces a pointer referencing that memory.
390389

391390
<div class="warning">
392391
Warning:
393-
The two pointers are not equivalent.
394-
Dereferencing the pointer obtained from the address to pointer cast may be <a href="../behavior-considered-undefined.md">undefined behavior</a> if aliasing rules are not followed.
392+
This interacts with the Rust memory model, which is still under development.
393+
A pointer obtained from this cast may suffer additional restrictions even if it is bitwise equal to a valid pointer.
394+
Dereferencing such a pointer may be <a href="../behavior-considered-undefined.md">undefined behavior</a> if aliasing rules are not followed.
395395
</div>
396396

397+
A trivial example of sound address arithmetic:
398+
399+
```rust
400+
let mut values: [i32; 2] = [1, 2];
401+
let p1 = &mut values[0] as *mut i32;
402+
let first_address = p1 as usize;
403+
let second_address = first_address + 4;
404+
let p2 = second_address as *mut i32;
405+
unsafe {
406+
*p2 += 1;
407+
}
408+
assert_eq!(values[1], 3);
409+
```
410+
397411
## Assignment expressions
398412

399413
> **<sup>Syntax</sup>**\

0 commit comments

Comments
 (0)