From 8e91a51cd81de5cf686d21db891634fecdc250c0 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Tue, 2 Apr 2024 18:54:24 +0200 Subject: [PATCH 1/4] DOC: Add FFI example for slice::from_raw_parts() --- library/core/src/slice/raw.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 29a12f106c5ed..d001688d79d80 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -83,6 +83,27 @@ 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; +/// +/// unsafe extern "C" fn handle_slice(ptr: *const f32, len: usize) { +/// let data = if ptr.is_null() { +/// // `len` is assumed to be 0. +/// &[] +/// } else { +/// unsafe { slice::from_raw_parts(ptr, len) } +/// }; +/// dbg!(data); +/// // ... +/// } +/// ``` +/// /// [valid]: ptr#safety /// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] From 22319bf6ba861eb0b5efb81aaf7616db30f4872f Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Fri, 26 Apr 2024 20:44:59 +0200 Subject: [PATCH 2/4] Add "safety" comment --- library/core/src/slice/raw.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index d001688d79d80..8ff429218a4df 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -92,11 +92,16 @@ use crate::ub_checks; /// ``` /// use std::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 handle_slice(ptr: *const f32, len: usize) { /// let data = if ptr.is_null() { /// // `len` is assumed to be 0. /// &[] /// } else { +/// // SAFETY: see function docstring. /// unsafe { slice::from_raw_parts(ptr, len) } /// }; /// dbg!(data); From 4df1303cff1eeb3b0c7f00d70fecf160279e7263 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Fri, 26 Apr 2024 20:53:23 +0200 Subject: [PATCH 3/4] Extend the example code and assert the result --- library/core/src/slice/raw.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 8ff429218a4df..efdd210c1fac8 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -92,11 +92,13 @@ use crate::ub_checks; /// ``` /// 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 handle_slice(ptr: *const f32, len: usize) { +/// unsafe extern "C" fn sum_slice(ptr: *const f32, len: usize) -> f32 { /// let data = if ptr.is_null() { /// // `len` is assumed to be 0. /// &[] @@ -104,9 +106,14 @@ use crate::ub_checks; /// // SAFETY: see function docstring. /// unsafe { slice::from_raw_parts(ptr, len) } /// }; -/// dbg!(data); -/// // ... +/// data.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 From 30b676cc00324c16963ef529ba37b49e0200ac5f Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Fri, 26 Apr 2024 21:18:00 +0200 Subject: [PATCH 4/4] Add missing .into_iter() --- library/core/src/slice/raw.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index efdd210c1fac8..a42c2cc4e63a9 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -106,7 +106,7 @@ use crate::ub_checks; /// // SAFETY: see function docstring. /// unsafe { slice::from_raw_parts(ptr, len) } /// }; -/// data.sum() +/// data.into_iter().sum() /// } /// /// // This could be the result of C++'s std::vector::data():