A Firehose of Rust

for busy people who know some C++

A dangling pointer
C++
Rust
C++
Rust
A borrowing view
C++
Rust
C++
Rust
A long-lived container
C++
Rust
C++
Rust
An invalid function
C++
Rust
C++
Rust
An invalid caller
Rust (previous)
Rust (with explicit lifetimes)
Rust (with explicit lifetimes)
Mutable aliasing
C++
Rust
Rust
Multiple references into an array
C++
Rust
Rust
There's more than one way to do it

  • just use indexes
  • pattern matching
  • split_at_mut
  • iter_mut
  • Cell<char>
  • RefCell<char>
  • unsafe code
split_at_mut
unsafe code ☠
Sidebar: mutable aliasing in assembly
Invalidating a reference by reallocating
C++
Rust
C++
Rust

Herb Sutter's aliased shared_ptr pitfall

Magical multithreading

C++

for loop

serial for_each

C++17 parallel for_each

Rust

for loop

serial for_each

Rayon parallel for_each

Tragical multithreading

C++

for loop

serial for_each

C++17 parallel for_each

Rust

for loop

serial for_each

Rayon parallel for_each

Rayon parallel for_each
How does Rust know?
Iterator
ParallelIterator
Synchronizing shared state

C++

atomic<int>

mutex

Rust

AtomicI32

Mutex<i32>

Moving a string
C++
one string allocation
three string destructors
Rust
one string allocation
one string destructor
Copying a string
C++
three string allocations
three string destructors
Rust
three string allocations
three string destructors
Accessing a moved-from object
C++
on my box:
s1 == ""
Rust
Rust
Moving a borrowed object
C++
on my box:
my_view == "\0bcde"
Rust
Rust
Moving a string again
C++
Rust
Rust
Moving through a reference
C++
on my box:
s1 == ""
s2 == "foo"
Rust
Rust
There's more than one way to do it
mem::swap
s1 == ""
s2 == "foo"
Option::take
s1 == None
s2 == "foo"
Vec::remove
v == ["bar", "baz"]
s2 == "foo"
The drop function
C++
Rust
Surprise: drop is the empty function

Move Semantics Tradeoffs

C++ strengths

  • Immovable types are supported.
    • mutex in C++ doesn't require heap allocation. Mutex in Rust does, to make itself movable on Unix.
  • Complex moves are supported.
    • GCC string has a branch-free small string optimization. This isn't possible in Rust, because it's not bitwise movable.

Rust strengths

  • All types are movable, and moves are infallible.
    • Constructors are regular functions; new isn't a keyword.
    • Vec growing and shifting can always memmove.
  • Types don't need a moved-from state.
    • unique_ptr<T> in C++ has to be nullable to be movable, but Box<T> in Rust doesn't.
Sidebar: memmove in Vec::remove

Putting it all together

Arc<Mutex<String>>
A mutex on the stack
C++
Rust
Rust
How does Rust know?
for_each
spawn
A mutex on the heap
C++
Rust
Forgetting the mutex
C++
Rust
C++
Rust
Writing under a read lock
C++
Rust
Rust

Louis Brandy's vexing parse

Rust giveth and Rust taketh away
C++
Rust
Rust giveth and Rust taketh away