Skip to content

Commit

Permalink
Fix example of niche optimization in Smart Pointers / Box<T> (#1946)
Browse files Browse the repository at this point in the history
Example with linked list replaced by example with Option
  • Loading branch information
DmitryMilk committed Mar 28, 2024
1 parent 6064631 commit b38d429
Showing 1 changed file with 21 additions and 23 deletions.
44 changes: 21 additions & 23 deletions src/smart-pointers/box.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,34 +89,32 @@ fn main() {

## Niche Optimization

Though `Box` looks like `std::unique_ptr` in C++, it cannot be empty/null. This
makes `Box` one of the types that allow the compiler to optimize storage of some
enums.

For example, `Option<Box<T>>` has the same size, as just `Box<T>`, because
compiler uses NULL-value to discriminate variants instead of using explicit tag
(["Null Pointer Optimization"](https://doc.rust-lang.org/std/option/#representation)):

```rust,editable
#[derive(Debug)]
enum List<T> {
Element(T, Box<List<T>>),
Nil,
}
use std::mem::size_of_val;
struct Item(String);
fn main() {
let list: List<i32> =
List::Element(1, Box::new(List::Element(2, Box::new(List::Nil))));
println!("{list:?}");
}
```
let just_box: Box<Item> = Box::new(Item("Just box".into()));
let optional_box: Option<Box<Item>> =
Some(Box::new(Item("Optional box".into())));
let none: Option<Box<Item>> = None;
A `Box` cannot be empty, so the pointer is always valid and non-`null`. This
allows the compiler to optimize the memory layout:
assert_eq!(size_of_val(&just_box), size_of_val(&optional_box));
assert_eq!(size_of_val(&just_box), size_of_val(&none));
```bob
Stack Heap
.- - - - - - - - - - - - - - . .- - - - - - - - - - - - - -.
: : : :
: list : : :
: +---------+----+----+ : : +---------+----+----+ :
: | Element | 1 | o--+----+-----+--->| Element | 2 | // | :
: +---------+----+----+ : : +---------+----+----+ :
: : : :
: : : :
'- - - - - - - - - - - - - - ' '- - - - - - - - - - - - - -'
println!("Size of just_box: {}", size_of_val(&just_box));
println!("Size of optional_box: {}", size_of_val(&optional_box));
println!("Size of none: {}", size_of_val(&none));
}
```

</details>

0 comments on commit b38d429

Please sign in to comment.