Skip to content

Commit ead1159

Browse files
committed
Use Niko's wording
1 parent 812ec6a commit ead1159

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

src/liballoc/boxed.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,25 @@
6363
//! T` obtained from `Box::<T>::into_raw` may be deallocated using the
6464
//! [`Global`] allocator with `Layout::for_value(&*value)`.
6565
//!
66-
//! `Box<T>` has the same ABI as `&mut T`. In particular, when `T: Sized`,
67-
//! this allows using `Box<T>` in FFI:
66+
//! So long as `T: Sized`, a `Box<T>` is guaranteed to be represented as a
67+
//! single pointer and is also ABI-compatible with C pointers (i.e. the C type
68+
//! `T*`). This means that you have Rust code which passes ownership of a
69+
//! `Box<T>` to C code by using `Box<T>` as the type on the Rust side, and
70+
//! `T*` as the corresponding type on the C side. As an example, consider this
71+
//! C header which declares functions that create and destroy some kind of
72+
//! `Foo` value:
6873
//!
6974
//! ```c
7075
//! /* C header */
7176
//! struct Foo* foo_new(void); /* Returns ownership to the caller */
7277
//! void foo_delete(struct Foo*); /* Takes ownership from the caller */
7378
//! ```
79+
//!
80+
//! These two functions might be implemented in Rust as follows. Here, the
81+
//! `struct Foo*` type from C is translated to `Box<Foo>`, which captures
82+
//! the ownership constraints. Note also that the nullable argument to
83+
//! `foo_delete` is represented in Rust as `Option<Box<Foo>>`, since `Box<Foo>`
84+
//! cannot be null.
7485
//!
7586
//! ```
7687
//! #[repr(C)]
@@ -84,6 +95,14 @@
8495
//! #[no_mangle]
8596
//! pub extern "C" fn foo_delete(_: Option<Box<Foo>>) {}
8697
//! ```
98+
//!
99+
//! Even though `Box<T>` has the same representation and C ABI as a C pointer,
100+
//! this does not mean that you can convert an arbitrary `T*` into a `Box<T>`
101+
//! and expect things to work. `Box<T>` values will always be fully aligned,
102+
//! non-null pointers. Moreover, the destructor for `Box<T>` will attempt to
103+
//! free the value with the global allocator. In general, the best practice
104+
//! is to only use `Box<T>` for pointers that originated from the global
105+
//! allocator.
87106
//!
88107
//! [dereferencing]: ../../std/ops/trait.Deref.html
89108
//! [`Box`]: struct.Box.html

0 commit comments

Comments
 (0)