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