Skip to content

Commit f34a622

Browse files
authored
Merge pull request #970 from ben0x539/cast
Document raw pointer <-> usize casts.
2 parents 5aa457b + dc1931a commit f34a622

File tree

1 file changed

+69
-29
lines changed

1 file changed

+69
-29
lines changed

src/expressions/operator-expr.md

+69-29
Original file line numberDiff line numberDiff line change
@@ -337,35 +337,29 @@ reference types and `mut` or `const` in pointer types.
337337

338338
### Semantics
339339

340-
* Numeric cast
341-
* Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
342-
* Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
343-
truncate
344-
* Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
345-
* zero-extend if the source is unsigned
346-
* sign-extend if the source is signed
347-
* Casting from a float to an integer will round the float towards zero
348-
* `NaN` will return `0`
349-
* Values larger than the maximum integer value will saturate to the
350-
maximum value of the integer type.
351-
* Values smaller than the minimum integer value will saturate to the
352-
minimum value of the integer type.
353-
* Casting from an integer to float will produce the closest possible float \*
354-
* if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
355-
* on overflow, infinity (of the same sign as the input) is produced
356-
* note: with the current set of numeric types, overflow can only happen
357-
on `u128 as f32` for values greater or equal to `f32::MAX + (0.5 ULP)`
358-
* Casting from an f32 to an f64 is perfect and lossless
359-
* Casting from an f64 to an f32 will produce the closest possible f32 \*\*
360-
* if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
361-
* on overflow, infinity (of the same sign as the input) is produced
362-
* Enum cast
363-
* Casts an enum to its discriminant, then uses a numeric cast if needed.
364-
* Primitive to integer cast
365-
* `false` casts to `0`, `true` casts to `1`
366-
* `char` casts to the value of the code point, then uses a numeric cast if needed.
367-
* `u8` to `char` cast
368-
* Casts to the `char` with the corresponding code point.
340+
#### Numeric cast
341+
342+
* Casting between two integers of the same size (e.g. i32 -> u32) is a no-op
343+
* Casting from a larger integer to a smaller integer (e.g. u32 -> u8) will
344+
truncate
345+
* Casting from a smaller integer to a larger integer (e.g. u8 -> u32) will
346+
* zero-extend if the source is unsigned
347+
* sign-extend if the source is signed
348+
* Casting from a float to an integer will round the float towards zero
349+
* `NaN` will return `0`
350+
* Values larger than the maximum integer value will saturate to the
351+
maximum value of the integer type.
352+
* Values smaller than the minimum integer value will saturate to the
353+
minimum value of the integer type.
354+
* Casting from an integer to float will produce the closest possible float \*
355+
* if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
356+
* on overflow, infinity (of the same sign as the input) is produced
357+
* note: with the current set of numeric types, overflow can only happen
358+
on `u128 as f32` for values greater or equal to `f32::MAX + (0.5 ULP)`
359+
* Casting from an f32 to an f64 is perfect and lossless
360+
* Casting from an f64 to an f32 will produce the closest possible f32 \*\*
361+
* if necessary, rounding is according to `roundTiesToEven` mode \*\*\*
362+
* on overflow, infinity (of the same sign as the input) is produced
369363

370364
\* if integer-to-float casts with this rounding mode and overflow behavior are
371365
not supported natively by the hardware, these casts will likely be slower than
@@ -379,6 +373,51 @@ expected.
379373
number, preferring the one with an even least significant digit if exactly
380374
halfway between two floating point numbers.
381375

376+
#### Enum cast
377+
378+
Casts an enum to its discriminant, then uses a numeric cast if needed.
379+
380+
#### Primitive to integer cast
381+
382+
* `false` casts to `0`, `true` casts to `1`
383+
* `char` casts to the value of the code point, then uses a numeric cast if needed.
384+
385+
#### `u8` to `char` cast
386+
387+
Casts to the `char` with the corresponding code point.
388+
389+
#### Pointer to address cast
390+
391+
Casting from a raw pointer to an integer produces the machine address of the referenced memory.
392+
If the integer type is smaller than the pointer type, the address may be truncated; using `usize` avoids this.
393+
394+
#### Address to pointer cast
395+
396+
Casting from an integer to a raw pointer interprets the integer as a memory address and produces a pointer referencing that memory.
397+
398+
<div class="warning">
399+
400+
Warning:
401+
This interacts with the Rust memory model, which is still under development.
402+
A pointer obtained from this cast may suffer additional restrictions even if it is bitwise equal to a valid pointer.
403+
Dereferencing such a pointer may be [undefined behavior] if aliasing rules are not followed.
404+
405+
</div>
406+
407+
A trivial example of sound address arithmetic:
408+
409+
```rust
410+
let mut values: [i32; 2] = [1, 2];
411+
let p1: *mut i32 = values.as_mut_ptr();
412+
let first_address = p1 as usize;
413+
let second_address = first_address + 4; // 4 == size_of::<i32>()
414+
let p2 = second_address as *mut i32;
415+
unsafe {
416+
*p2 += 1;
417+
}
418+
assert_eq!(values[1], 3);
419+
```
420+
382421
## Assignment expressions
383422

384423
> **<sup>Syntax</sup>**\
@@ -489,6 +528,7 @@ See [this test] for an example of using this dependency.
489528
[logical xor]: ../types/boolean.md#logical-xor
490529
[mutable]: ../expressions.md#mutability
491530
[place expression]: ../expressions.md#place-expressions-and-value-expressions
531+
[undefined behavior]: ../behavior-considered-undefined.md
492532
[unit]: ../types/tuple.md
493533
[value expression]: ../expressions.md#place-expressions-and-value-expressions
494534
[temporary value]: ../expressions.md#temporaries

0 commit comments

Comments
 (0)