@@ -959,59 +959,134 @@ extern "rust-intrinsic" {
959
959
/// value is not necessarily valid to be used to actually access memory.
960
960
pub fn arith_offset < T > ( dst : * const T , offset : isize ) -> * const T ;
961
961
962
- /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
963
- /// and destination may *not* overlap.
962
+ /// Copies `count * size_of:: <T>() ` bytes from `src` to `dst`. The source
963
+ /// and destination must *not* overlap.
964
964
///
965
- /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
965
+ /// For regions of memory which might overlap, use [`copy`] instead.
966
+ ///
967
+ /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`].
968
+ ///
969
+ /// [`copy`]: ./fn.copy.html
970
+ /// [`memcpy`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memcpy
966
971
///
967
972
/// # Safety
968
973
///
969
- /// Beyond requiring that the program must be allowed to access both regions
970
- /// of memory, it is Undefined Behavior for source and destination to
971
- /// overlap. Care must also be taken with the ownership of `src` and
972
- /// `dst`. This method semantically moves the values of `src` into `dst`.
973
- /// However it does not drop the contents of `dst`, or prevent the contents
974
- /// of `src` from being dropped or used.
974
+ /// `copy_nonoverlapping` is unsafe because it dereferences a raw pointer.
975
+ /// The caller must ensure that `src` points to a valid sequence of type
976
+ /// `T`.
977
+ ///
978
+ /// # [Undefined Behavior]
979
+ ///
980
+ /// Behavior is undefined if any of the following conditions are violated:
981
+ ///
982
+ /// * The region of memory which begins at `src` and has a length of
983
+ /// `count * size_of::<T>()` bytes must be *both* valid and initialized.
984
+ ///
985
+ /// * The region of memory which begins at `dst` and has a length of
986
+ /// `count * size_of::<T>()` bytes must be valid (but may or may not be
987
+ /// initialized).
988
+ ///
989
+ /// * `src` must be properly aligned.
990
+ ///
991
+ /// * `dst` must be properly aligned.
992
+ ///
993
+ /// * The two regions of memory must *not* overlap.
994
+ ///
995
+ /// Additionally, if `T` is not [`Copy`](../marker/trait.Copy), only the region at `src` *or* the
996
+ /// region at `dst` can be used or dropped after calling
997
+ /// `copy_nonoverlapping`. `copy_nonoverlapping` creates bitwise copies of
998
+ /// `T`, regardless of whether `T: Copy`, which can result in undefined
999
+ /// behavior if both copies are used.
1000
+ ///
1001
+ /// [Undefined Behavior]: ../../reference/behavior-considered-undefined.html
975
1002
///
976
1003
/// # Examples
977
1004
///
978
- /// A safe swap function :
1005
+ /// Manually implement [`Vec::append`] :
979
1006
///
980
1007
/// ```
981
- /// use std::mem;
982
1008
/// use std::ptr;
983
1009
///
984
- /// # #[allow(dead_code)]
985
- /// fn swap<T>(x: &mut T, y: &mut T) {
1010
+ /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1011
+ /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1012
+ /// let src_len = src.len();
1013
+ /// let dst_len = dst.len();
1014
+ ///
1015
+ /// // Ensure that `dst` has enough capacity to hold all of `src`.
1016
+ /// dst.reserve(src_len);
1017
+ ///
986
1018
/// unsafe {
987
- /// // Give ourselves some scratch space to work with
988
- /// let mut t: T = mem::uninitialized();
1019
+ /// // The call to offset is always safe because `Vec` will never
1020
+ /// // allocate more than `isize::MAX` bytes.
1021
+ /// let dst = dst.as_mut_ptr().offset(dst_len as isize);
1022
+ /// let src = src.as_ptr();
1023
+ ///
1024
+ /// // The two regions cannot overlap becuase mutable references do
1025
+ /// // not alias, and two different vectors cannot own the same
1026
+ /// // memory.
1027
+ /// ptr::copy_nonoverlapping(src, dst, src_len);
1028
+ /// }
989
1029
///
990
- /// // Perform the swap, `&mut` pointers never alias
991
- /// ptr::copy_nonoverlapping(x, &mut t, 1);
992
- /// ptr::copy_nonoverlapping(y, x, 1);
993
- /// ptr::copy_nonoverlapping(&t, y, 1);
1030
+ /// unsafe {
1031
+ /// // Truncate `src` without dropping its contents.
1032
+ /// src.set_len(0);
994
1033
///
995
- /// // y and t now point to the same thing, but we need to completely forget `t`
996
- /// // because it's no longer relevant.
997
- /// mem::forget(t);
1034
+ /// // Notify `dst` that it now holds the contents of `src`.
1035
+ /// dst.set_len(dst_len + src_len);
998
1036
/// }
999
1037
/// }
1038
+ ///
1039
+ /// let mut a = vec!['r'];
1040
+ /// let mut b = vec!['u', 's', 't'];
1041
+ ///
1042
+ /// append(&mut a, &mut b);
1043
+ ///
1044
+ /// assert_eq!(a, &['r', 'u', 's', 't']);
1045
+ /// assert!(b.is_empty());
1000
1046
/// ```
1047
+ ///
1048
+ /// [`Vec::append()`]: ../vec/struct.Vec.html#method.append
1001
1049
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1002
1050
pub fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
1003
1051
1004
- /// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
1052
+ /// Copies `count * size_of:: <T>() ` bytes from `src` to `dst`. The source
1005
1053
/// and destination may overlap.
1006
1054
///
1007
- /// `copy` is semantically equivalent to C's `memmove`.
1055
+ /// If the source and destination will *never* overlap,
1056
+ /// [`copy_nonoverlapping`] can be used instead.
1057
+ ///
1058
+ /// `copy` is semantically equivalent to C's [`memmove`].
1059
+ ///
1060
+ /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
1061
+ /// [`memmove`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memmove
1008
1062
///
1009
1063
/// # Safety
1010
1064
///
1011
- /// Care must be taken with the ownership of `src` and `dst`.
1012
- /// This method semantically moves the values of `src` into `dst`.
1013
- /// However it does not drop the contents of `dst`, or prevent the contents of `src`
1014
- /// from being dropped or used.
1065
+ /// `copy` is unsafe because it dereferences a raw pointer. The caller must
1066
+ /// ensure that `src` points to a valid sequence of type `T`.
1067
+ ///
1068
+ /// # [Undefined Behavior]
1069
+ ///
1070
+ /// Behavior is undefined if any of the following conditions are violated:
1071
+ ///
1072
+ /// * The region of memory which begins at `src` and has a length of
1073
+ /// `count * size_of::<T>()` bytes must be *both* valid and initialized.
1074
+ ///
1075
+ /// * The region of memory which begins at `dst` and has a length of
1076
+ /// `count * size_of::<T>()` bytes must be valid (but may or may not be
1077
+ /// initialized).
1078
+ ///
1079
+ /// * `src` must be properly aligned.
1080
+ ///
1081
+ /// * `dst` must be properly aligned.
1082
+ ///
1083
+ /// Additionally, if `T` is not [`Copy`], only the region at `src` *or* the
1084
+ /// region at `dst` can be used or dropped after calling `copy`. `copy`
1085
+ /// creates bitwise copies of `T`, regardless of whether `T: Copy`, which
1086
+ /// can result in undefined behavior if both copies are used.
1087
+ ///
1088
+ /// [`Copy`]: ../marker/trait.Copy.html
1089
+ /// [Undefined Behavior]: ../../reference/behavior-considered-undefined.html
1015
1090
///
1016
1091
/// # Examples
1017
1092
///
@@ -1028,15 +1103,39 @@ extern "rust-intrinsic" {
1028
1103
/// dst
1029
1104
/// }
1030
1105
/// ```
1031
- ///
1032
1106
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1033
1107
pub fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
1034
1108
1035
- /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
1036
- /// bytes of memory starting at `dst` to `val`.
1109
+ /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
1110
+ /// `val`.
1111
+ ///
1112
+ /// `write_bytes` is semantically equivalent to C's [`memset`].
1113
+ ///
1114
+ /// [`memset`]: https://www.gnu.org/software/libc/manual/html_node/Copying-Strings-and-Arrays.html#index-memset
1115
+ ///
1116
+ /// # Safety
1117
+ ///
1118
+ /// `write_bytes` is unsafe because it dereferences a raw pointer. The
1119
+ /// caller must ensure that the poiinter points to a valid value of type `T`.
1120
+ ///
1121
+ /// # [Undefined Behavior]
1122
+ ///
1123
+ /// Behavior is undefined if any of the following conditions are violated:
1124
+ ///
1125
+ /// * The region of memory which begins at `dst` and has a length of
1126
+ /// `count` bytes must be valid.
1127
+ ///
1128
+ /// * `dst` must be properly aligned.
1129
+ ///
1130
+ /// Additionally, the caller must ensure that writing `count` bytes to the
1131
+ /// given region of memory results in a valid value of `T`. Creating an
1132
+ /// invalid value of `T` can result in undefined behavior. An example is
1133
+ /// provided below.
1037
1134
///
1038
1135
/// # Examples
1039
1136
///
1137
+ /// Basic usage:
1138
+ ///
1040
1139
/// ```
1041
1140
/// use std::ptr;
1042
1141
///
@@ -1047,6 +1146,22 @@ extern "rust-intrinsic" {
1047
1146
/// }
1048
1147
/// assert_eq!(vec, [b'a', b'a', 0, 0]);
1049
1148
/// ```
1149
+ ///
1150
+ /// Creating an invalid value:
1151
+ ///
1152
+ /// ```ignore
1153
+ /// use std::{mem, ptr};
1154
+ ///
1155
+ /// let mut v = Box::new(0i32);
1156
+ ///
1157
+ /// unsafe {
1158
+ /// // Leaks the previously held value by overwriting the `Box<T>` with
1159
+ /// // a null pointer.
1160
+ /// ptr::write_bytes(&mut v, 0, mem::size_of::<Box<i32>>());
1161
+ /// }
1162
+ ///
1163
+ /// // At this point, using or dropping `v` results in undefined behavior.
1164
+ /// ```
1050
1165
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1051
1166
pub fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) ;
1052
1167
0 commit comments