1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-06-17 22:57:35 +02:00

Rework example to compare to UB in C

This commit is contained in:
Nicole LeGare
2025-06-09 14:02:33 -07:00
parent 24a2642758
commit b01299bc3b

View File

@ -20,14 +20,19 @@ fn main() {
We can also look at a case where these rules prevent incorrect optimizations: We can also look at a case where these rules prevent incorrect optimizations:
```rust,editable,compile_fail ```rust,editable,compile_fail
fn sum_and_zero(a: &mut i32, b: &mut i32) { fn swap_and_increment(a: &mut i32, b: &mut i32) {
*a = *a + *b; *a = *a + 1;
*b = 0;
let tmp = *a;
*a = *b;
*b = tmp;
*b = *a + 1;
} }
fn main() { fn main() {
let mut x = 5; let mut x = 1;
sum_and_zero(&mut x, &mut x); swap_and_increment(&mut x, &mut x);
} }
``` ```
@ -37,16 +42,28 @@ fn main() {
can potentially invalidate existing references to the collection's elements if can potentially invalidate existing references to the collection's elements if
the collection has to reallocate. the collection has to reallocate.
- In the second case, the aliasing rule prevents mis-compilation: The output of - In the second case, the aliasing rule prevents mis-compilation: In the C
`sum_and_zero` depends on the ordering of the two operations, which means if equivalent of this function, the program produces different results when
the compiler swaps the order of these operations (which it's allowed to do) it compiled with optimzations enabled.
changes the result.
- The equivalent code in C exhibits undefined behavior, which may result in - Show students [the C version of this on Godbolt][unoptimized]. By default,
mis-compilation and unexpected behavior, even if it doesn't cause a crash. with no optimizations enabled it will print `x = 3`. But
[enabling optimizations][optimized] causes it to instead print `x = 2`.
- Note the use of the `restrict` keyword in the C example. This tells the
compiler that `a` and `b` cannot alias, but nothing prevents you from
violating that requirement. The compiler will silently produce the wrong
behavior.
- In the Rust version, using `&mut` automatically implies the same
restriction, and the compiler statically prevents violations of this
requirement.
- Rust's aliasing rules provide strong guarantees about how references can - Rust's aliasing rules provide strong guarantees about how references can
alias, allowing the compiler to apply optimizations without breaking the alias, allowing the compiler to apply optimizations without breaking the
semantics of your program. semantics of your program.
</details> </details>
[unoptimized]: https://godbolt.org/z/9EGh6eMxE
[optimized]: https://godbolt.org/z/Kxsf8sahT