about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <46493976+workingjubilee@users.noreply.github.com>2024-06-12 03:57:18 -0700
committerGitHub <noreply@github.com>2024-06-12 03:57:18 -0700
commit8d3b9a19cfdf5ee0561e43f3176d9501bcf2c4d9 (patch)
treed4e773cfe9b080ee36f5b7a812f0e306e974c727
parentbdb1b7f5d9715cc96cb437134eff93fa229defd1 (diff)
parent30b676cc00324c16963ef529ba37b49e0200ac5f (diff)
downloadrust-8d3b9a19cfdf5ee0561e43f3176d9501bcf2c4d9.tar.gz
rust-8d3b9a19cfdf5ee0561e43f3176d9501bcf2c4d9.zip
Rollup merge of #123374 - mgeier:doc-slice-from-raw-parts, r=scottmcm
DOC: Add FFI example for slice::from_raw_parts()

For some discussion, see https://users.rust-lang.org/t/missing-guidance-on-converting-ffi-ptr-length-to-slice/106048

See also #120608.
-rw-r--r--library/core/src/slice/raw.rs33
1 files changed, 33 insertions, 0 deletions
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 3f4305866e6..280aead270e 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -82,6 +82,39 @@ use crate::ub_checks;
 /// }
 /// ```
 ///
+/// ### FFI: Handling null pointers
+///
+/// In languages such as C++, pointers to empty collections are not guaranteed to be non-null.
+/// When accepting such pointers, they have to be checked for null-ness to avoid undefined
+/// behavior.
+///
+/// ```
+/// use std::slice;
+///
+/// /// Sum the elements of an FFI slice.
+/// ///
+/// /// # Safety
+/// ///
+/// /// If ptr is not NULL, it must be correctly aligned and
+/// /// point to `len` initialized items of type `f32`.
+/// unsafe extern "C" fn sum_slice(ptr: *const f32, len: usize) -> f32 {
+///     let data = if ptr.is_null() {
+///         // `len` is assumed to be 0.
+///         &[]
+///     } else {
+///         // SAFETY: see function docstring.
+///         unsafe { slice::from_raw_parts(ptr, len) }
+///     };
+///     data.into_iter().sum()
+/// }
+///
+/// // This could be the result of C++'s std::vector::data():
+/// let ptr = std::ptr::null();
+/// // And this could be std::vector::size():
+/// let len = 0;
+/// assert_eq!(unsafe { sum_slice(ptr, len) }, 0.0);
+/// ```
+///
 /// [valid]: ptr#safety
 /// [`NonNull::dangling()`]: ptr::NonNull::dangling
 #[inline]