2 use crate::cmp::Ordering::{self, Equal, Greater, Less};
5 use crate::slice::{self, SliceIndex};
8 impl<T: ?Sized> *const T {
9 /// Returns `true` if the pointer is null.
11 /// Note that unsized types have many possible null pointers, as only the
12 /// raw data pointer is considered, not their length, vtable, etc.
13 /// Therefore, two pointers that are null may still not compare equal to
16 /// ## Behavior during const evaluation
18 /// When this function is used during const evaluation, it may return `false` for pointers
19 /// that turn out to be null at runtime. Specifically, when a pointer to some memory
20 /// is offset beyond its bounds in such a way that the resulting pointer is null,
21 /// the function will still return `false`. There is no way for CTFE to know
22 /// the absolute position of that memory, so we cannot tell if the pointer is
30 /// let s: &str = "Follow the rabbit";
31 /// let ptr: *const u8 = s.as_ptr();
32 /// assert!(!ptr.is_null());
34 #[stable(feature = "rust1", since = "1.0.0")]
35 #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
37 pub const fn is_null(self) -> bool {
38 // Compare via a cast to a thin pointer, so fat pointers are only
39 // considering their "data" part for null-ness.
40 (self as *const u8).guaranteed_eq(null())
43 /// Casts to a pointer of another type.
44 #[stable(feature = "ptr_cast", since = "1.38.0")]
45 #[rustc_const_stable(feature = "const_ptr_cast", since = "1.38.0")]
47 pub const fn cast<U>(self) -> *const U {
51 /// Decompose a (possibly wide) pointer into its address and metadata components.
53 /// The pointer can be later reconstructed with [`from_raw_parts`].
54 #[unstable(feature = "ptr_metadata", issue = "81513")]
55 #[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
57 pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata) {
58 (self.cast(), metadata(self))
61 /// Returns `None` if the pointer is null, or else returns a shared reference to
62 /// the value wrapped in `Some`. If the value may be uninitialized, [`as_uninit_ref`]
63 /// must be used instead.
65 /// [`as_uninit_ref`]: #method.as_uninit_ref
69 /// When calling this method, you have to ensure that *either* the pointer is null *or*
70 /// all of the following is true:
72 /// * The pointer must be properly aligned.
74 /// * It must be "dereferencable" in the sense defined in [the module documentation].
76 /// * The pointer must point to an initialized instance of `T`.
78 /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
79 /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
80 /// In particular, for the duration of this lifetime, the memory the pointer points to must
81 /// not get mutated (except inside `UnsafeCell`).
83 /// This applies even if the result of this method is unused!
84 /// (The part about being initialized is not yet fully decided, but until
85 /// it is, the only safe approach is to ensure that they are indeed initialized.)
87 /// [the module documentation]: crate::ptr#safety
94 /// let ptr: *const u8 = &10u8 as *const u8;
97 /// if let Some(val_back) = ptr.as_ref() {
98 /// println!("We got back the value: {}!", val_back);
103 /// # Null-unchecked version
105 /// If you are sure the pointer can never be null and are looking for some kind of
106 /// `as_ref_unchecked` that returns the `&T` instead of `Option<&T>`, know that you can
107 /// dereference the pointer directly.
110 /// let ptr: *const u8 = &10u8 as *const u8;
113 /// let val_back = &*ptr;
114 /// println!("We got back the value: {}!", val_back);
117 #[stable(feature = "ptr_as_ref", since = "1.9.0")]
119 pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
120 // SAFETY: the caller must guarantee that `self` is valid
121 // for a reference if it isn't null.
122 if self.is_null() { None } else { unsafe { Some(&*self) } }
125 /// Returns `None` if the pointer is null, or else returns a shared reference to
126 /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
127 /// that the value has to be initialized.
129 /// [`as_ref`]: #method.as_ref
133 /// When calling this method, you have to ensure that *either* the pointer is null *or*
134 /// all of the following is true:
136 /// * The pointer must be properly aligned.
138 /// * It must be "dereferencable" in the sense defined in [the module documentation].
140 /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
141 /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
142 /// In particular, for the duration of this lifetime, the memory the pointer points to must
143 /// not get mutated (except inside `UnsafeCell`).
145 /// This applies even if the result of this method is unused!
147 /// [the module documentation]: crate::ptr#safety
154 /// #![feature(ptr_as_uninit)]
156 /// let ptr: *const u8 = &10u8 as *const u8;
159 /// if let Some(val_back) = ptr.as_uninit_ref() {
160 /// println!("We got back the value: {}!", val_back.assume_init());
165 #[unstable(feature = "ptr_as_uninit", issue = "75402")]
166 pub unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
170 // SAFETY: the caller must guarantee that `self` meets all the
171 // requirements for a reference.
172 if self.is_null() { None } else { Some(unsafe { &*(self as *const MaybeUninit<T>) }) }
175 /// Calculates the offset from a pointer.
177 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
178 /// offset of `3 * size_of::<T>()` bytes.
182 /// If any of the following conditions are violated, the result is Undefined
185 /// * Both the starting and resulting pointer must be either in bounds or one
186 /// byte past the end of the same [allocated object].
188 /// * The computed offset, **in bytes**, cannot overflow an `isize`.
190 /// * The offset being in bounds cannot rely on "wrapping around" the address
191 /// space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
193 /// The compiler and standard library generally tries to ensure allocations
194 /// never reach a size where an offset is a concern. For instance, `Vec`
195 /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
196 /// `vec.as_ptr().add(vec.len())` is always safe.
198 /// Most platforms fundamentally can't even construct such an allocation.
199 /// For instance, no known 64-bit platform can ever serve a request
200 /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
201 /// However, some 32-bit and 16-bit platforms may successfully serve a request for
202 /// more than `isize::MAX` bytes with things like Physical Address
203 /// Extension. As such, memory acquired directly from allocators or memory
204 /// mapped files *may* be too large to handle with this function.
206 /// Consider using [`wrapping_offset`] instead if these constraints are
207 /// difficult to satisfy. The only advantage of this method is that it
208 /// enables more aggressive compiler optimizations.
210 /// [`wrapping_offset`]: #method.wrapping_offset
211 /// [allocated object]: crate::ptr#allocated-object
218 /// let s: &str = "123";
219 /// let ptr: *const u8 = s.as_ptr();
222 /// println!("{}", *ptr.offset(1) as char);
223 /// println!("{}", *ptr.offset(2) as char);
226 #[stable(feature = "rust1", since = "1.0.0")]
227 #[must_use = "returns a new pointer rather than modifying its argument"]
228 #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
230 pub const unsafe fn offset(self, count: isize) -> *const T
234 // SAFETY: the caller must uphold the safety contract for `offset`.
235 unsafe { intrinsics::offset(self, count) }
238 /// Calculates the offset from a pointer using wrapping arithmetic.
240 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
241 /// offset of `3 * size_of::<T>()` bytes.
245 /// This operation itself is always safe, but using the resulting pointer is not.
247 /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
248 /// be used to read or write other allocated objects.
250 /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z`
251 /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
252 /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
253 /// `x` and `y` point into the same allocated object.
255 /// Compared to [`offset`], this method basically delays the requirement of staying within the
256 /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object
257 /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a
258 /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`]
259 /// can be optimized better and is thus preferable in performance-sensitive code.
261 /// The delayed check only considers the value of the pointer that was dereferenced, not the
262 /// intermediate values used during the computation of the final result. For example,
263 /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other
264 /// words, leaving the allocated object and then re-entering it later is permitted.
266 /// [`offset`]: #method.offset
267 /// [allocated object]: crate::ptr#allocated-object
274 /// // Iterate using a raw pointer in increments of two elements
275 /// let data = [1u8, 2, 3, 4, 5];
276 /// let mut ptr: *const u8 = data.as_ptr();
278 /// let end_rounded_up = ptr.wrapping_offset(6);
280 /// // This loop prints "1, 3, 5, "
281 /// while ptr != end_rounded_up {
283 /// print!("{}, ", *ptr);
285 /// ptr = ptr.wrapping_offset(step);
288 #[stable(feature = "ptr_wrapping_offset", since = "1.16.0")]
289 #[must_use = "returns a new pointer rather than modifying its argument"]
290 #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
292 pub const fn wrapping_offset(self, count: isize) -> *const T
296 // SAFETY: the `arith_offset` intrinsic has no prerequisites to be called.
297 unsafe { intrinsics::arith_offset(self, count) }
300 /// Calculates the distance between two pointers. The returned value is in
301 /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
303 /// This function is the inverse of [`offset`].
305 /// [`offset`]: #method.offset
309 /// If any of the following conditions are violated, the result is Undefined
312 /// * Both the starting and other pointer must be either in bounds or one
313 /// byte past the end of the same [allocated object].
315 /// * Both pointers must be *derived from* a pointer to the same object.
316 /// (See below for an example.)
318 /// * The distance between the pointers, in bytes, must be an exact multiple
319 /// of the size of `T`.
321 /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
323 /// * The distance being in bounds cannot rely on "wrapping around" the address space.
325 /// Rust types are never larger than `isize::MAX` and Rust allocations never wrap around the
326 /// address space, so two pointers within some value of any Rust type `T` will always satisfy
327 /// the last two conditions. The standard library also generally ensures that allocations
328 /// never reach a size where an offset is a concern. For instance, `Vec` and `Box` ensure they
329 /// never allocate more than `isize::MAX` bytes, so `ptr_into_vec.offset_from(vec.as_ptr())`
330 /// always satisfies the last two conditions.
332 /// Most platforms fundamentally can't even construct such a large allocation.
333 /// For instance, no known 64-bit platform can ever serve a request
334 /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
335 /// However, some 32-bit and 16-bit platforms may successfully serve a request for
336 /// more than `isize::MAX` bytes with things like Physical Address
337 /// Extension. As such, memory acquired directly from allocators or memory
338 /// mapped files *may* be too large to handle with this function.
339 /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
340 /// such large allocations either.)
342 /// [`add`]: #method.add
343 /// [allocated object]: crate::ptr#allocated-object
347 /// This function panics if `T` is a Zero-Sized Type ("ZST").
355 /// let ptr1: *const i32 = &a[1];
356 /// let ptr2: *const i32 = &a[3];
358 /// assert_eq!(ptr2.offset_from(ptr1), 2);
359 /// assert_eq!(ptr1.offset_from(ptr2), -2);
360 /// assert_eq!(ptr1.offset(2), ptr2);
361 /// assert_eq!(ptr2.offset(-2), ptr1);
365 /// *Incorrect* usage:
368 /// let ptr1 = Box::into_raw(Box::new(0u8)) as *const u8;
369 /// let ptr2 = Box::into_raw(Box::new(1u8)) as *const u8;
370 /// let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
371 /// // Make ptr2_other an "alias" of ptr2, but derived from ptr1.
372 /// let ptr2_other = (ptr1 as *const u8).wrapping_offset(diff);
373 /// assert_eq!(ptr2 as usize, ptr2_other as usize);
374 /// // Since ptr2_other and ptr2 are derived from pointers to different objects,
375 /// // computing their offset is undefined behavior, even though
376 /// // they point to the same address!
378 /// let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
381 #[stable(feature = "ptr_offset_from", since = "1.47.0")]
382 #[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "41079")]
384 pub const unsafe fn offset_from(self, origin: *const T) -> isize
388 let pointee_size = mem::size_of::<T>();
389 assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
390 // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`.
391 unsafe { intrinsics::ptr_offset_from(self, origin) }
394 /// Returns whether two pointers are guaranteed to be equal.
396 /// At runtime this function behaves like `self == other`.
397 /// However, in some contexts (e.g., compile-time evaluation),
398 /// it is not always possible to determine equality of two pointers, so this function may
399 /// spuriously return `false` for pointers that later actually turn out to be equal.
400 /// But when it returns `true`, the pointers are guaranteed to be equal.
402 /// This function is the mirror of [`guaranteed_ne`], but not its inverse. There are pointer
403 /// comparisons for which both functions return `false`.
405 /// [`guaranteed_ne`]: #method.guaranteed_ne
407 /// The return value may change depending on the compiler version and unsafe code might not
408 /// rely on the result of this function for soundness. It is suggested to only use this function
409 /// for performance optimizations where spurious `false` return values by this function do not
410 /// affect the outcome, but just the performance.
411 /// The consequences of using this method to make runtime and compile-time code behave
412 /// differently have not been explored. This method should not be used to introduce such
413 /// differences, and it should also not be stabilized before we have a better understanding
415 #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
416 #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
418 pub const fn guaranteed_eq(self, other: *const T) -> bool
422 intrinsics::ptr_guaranteed_eq(self, other)
425 /// Returns whether two pointers are guaranteed to be unequal.
427 /// At runtime this function behaves like `self != other`.
428 /// However, in some contexts (e.g., compile-time evaluation),
429 /// it is not always possible to determine the inequality of two pointers, so this function may
430 /// spuriously return `false` for pointers that later actually turn out to be unequal.
431 /// But when it returns `true`, the pointers are guaranteed to be unequal.
433 /// This function is the mirror of [`guaranteed_eq`], but not its inverse. There are pointer
434 /// comparisons for which both functions return `false`.
436 /// [`guaranteed_eq`]: #method.guaranteed_eq
438 /// The return value may change depending on the compiler version and unsafe code might not
439 /// rely on the result of this function for soundness. It is suggested to only use this function
440 /// for performance optimizations where spurious `false` return values by this function do not
441 /// affect the outcome, but just the performance.
442 /// The consequences of using this method to make runtime and compile-time code behave
443 /// differently have not been explored. This method should not be used to introduce such
444 /// differences, and it should also not be stabilized before we have a better understanding
446 #[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
447 #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
449 pub const fn guaranteed_ne(self, other: *const T) -> bool
453 intrinsics::ptr_guaranteed_ne(self, other)
456 /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
458 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
459 /// offset of `3 * size_of::<T>()` bytes.
463 /// If any of the following conditions are violated, the result is Undefined
466 /// * Both the starting and resulting pointer must be either in bounds or one
467 /// byte past the end of the same [allocated object].
469 /// * The computed offset, **in bytes**, cannot overflow an `isize`.
471 /// * The offset being in bounds cannot rely on "wrapping around" the address
472 /// space. That is, the infinite-precision sum must fit in a `usize`.
474 /// The compiler and standard library generally tries to ensure allocations
475 /// never reach a size where an offset is a concern. For instance, `Vec`
476 /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
477 /// `vec.as_ptr().add(vec.len())` is always safe.
479 /// Most platforms fundamentally can't even construct such an allocation.
480 /// For instance, no known 64-bit platform can ever serve a request
481 /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
482 /// However, some 32-bit and 16-bit platforms may successfully serve a request for
483 /// more than `isize::MAX` bytes with things like Physical Address
484 /// Extension. As such, memory acquired directly from allocators or memory
485 /// mapped files *may* be too large to handle with this function.
487 /// Consider using [`wrapping_add`] instead if these constraints are
488 /// difficult to satisfy. The only advantage of this method is that it
489 /// enables more aggressive compiler optimizations.
491 /// [`wrapping_add`]: #method.wrapping_add
492 /// [allocated object]: crate::ptr#allocated-object
499 /// let s: &str = "123";
500 /// let ptr: *const u8 = s.as_ptr();
503 /// println!("{}", *ptr.add(1) as char);
504 /// println!("{}", *ptr.add(2) as char);
507 #[stable(feature = "pointer_methods", since = "1.26.0")]
508 #[must_use = "returns a new pointer rather than modifying its argument"]
509 #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
511 pub const unsafe fn add(self, count: usize) -> Self
515 // SAFETY: the caller must uphold the safety contract for `offset`.
516 unsafe { self.offset(count as isize) }
519 /// Calculates the offset from a pointer (convenience for
520 /// `.offset((count as isize).wrapping_neg())`).
522 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
523 /// offset of `3 * size_of::<T>()` bytes.
527 /// If any of the following conditions are violated, the result is Undefined
530 /// * Both the starting and resulting pointer must be either in bounds or one
531 /// byte past the end of the same [allocated object].
533 /// * The computed offset cannot exceed `isize::MAX` **bytes**.
535 /// * The offset being in bounds cannot rely on "wrapping around" the address
536 /// space. That is, the infinite-precision sum must fit in a usize.
538 /// The compiler and standard library generally tries to ensure allocations
539 /// never reach a size where an offset is a concern. For instance, `Vec`
540 /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
541 /// `vec.as_ptr().add(vec.len()).sub(vec.len())` is always safe.
543 /// Most platforms fundamentally can't even construct such an allocation.
544 /// For instance, no known 64-bit platform can ever serve a request
545 /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
546 /// However, some 32-bit and 16-bit platforms may successfully serve a request for
547 /// more than `isize::MAX` bytes with things like Physical Address
548 /// Extension. As such, memory acquired directly from allocators or memory
549 /// mapped files *may* be too large to handle with this function.
551 /// Consider using [`wrapping_sub`] instead if these constraints are
552 /// difficult to satisfy. The only advantage of this method is that it
553 /// enables more aggressive compiler optimizations.
555 /// [`wrapping_sub`]: #method.wrapping_sub
556 /// [allocated object]: crate::ptr#allocated-object
563 /// let s: &str = "123";
566 /// let end: *const u8 = s.as_ptr().add(3);
567 /// println!("{}", *end.sub(1) as char);
568 /// println!("{}", *end.sub(2) as char);
571 #[stable(feature = "pointer_methods", since = "1.26.0")]
572 #[must_use = "returns a new pointer rather than modifying its argument"]
573 #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
575 pub const unsafe fn sub(self, count: usize) -> Self
579 // SAFETY: the caller must uphold the safety contract for `offset`.
580 unsafe { self.offset((count as isize).wrapping_neg()) }
583 /// Calculates the offset from a pointer using wrapping arithmetic.
584 /// (convenience for `.wrapping_offset(count as isize)`)
586 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
587 /// offset of `3 * size_of::<T>()` bytes.
591 /// This operation itself is always safe, but using the resulting pointer is not.
593 /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
594 /// be used to read or write other allocated objects.
596 /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z`
597 /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
598 /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
599 /// `x` and `y` point into the same allocated object.
601 /// Compared to [`add`], this method basically delays the requirement of staying within the
602 /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object
603 /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a
604 /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`]
605 /// can be optimized better and is thus preferable in performance-sensitive code.
607 /// The delayed check only considers the value of the pointer that was dereferenced, not the
608 /// intermediate values used during the computation of the final result. For example,
609 /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
610 /// allocated object and then re-entering it later is permitted.
612 /// [`add`]: #method.add
613 /// [allocated object]: crate::ptr#allocated-object
620 /// // Iterate using a raw pointer in increments of two elements
621 /// let data = [1u8, 2, 3, 4, 5];
622 /// let mut ptr: *const u8 = data.as_ptr();
624 /// let end_rounded_up = ptr.wrapping_add(6);
626 /// // This loop prints "1, 3, 5, "
627 /// while ptr != end_rounded_up {
629 /// print!("{}, ", *ptr);
631 /// ptr = ptr.wrapping_add(step);
634 #[stable(feature = "pointer_methods", since = "1.26.0")]
635 #[must_use = "returns a new pointer rather than modifying its argument"]
636 #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
638 pub const fn wrapping_add(self, count: usize) -> Self
642 self.wrapping_offset(count as isize)
645 /// Calculates the offset from a pointer using wrapping arithmetic.
646 /// (convenience for `.wrapping_offset((count as isize).wrapping_neg())`)
648 /// `count` is in units of T; e.g., a `count` of 3 represents a pointer
649 /// offset of `3 * size_of::<T>()` bytes.
653 /// This operation itself is always safe, but using the resulting pointer is not.
655 /// The resulting pointer "remembers" the [allocated object] that `self` points to; it must not
656 /// be used to read or write other allocated objects.
658 /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z`
659 /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still
660 /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless
661 /// `x` and `y` point into the same allocated object.
663 /// Compared to [`sub`], this method basically delays the requirement of staying within the
664 /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object
665 /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a
666 /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`]
667 /// can be optimized better and is thus preferable in performance-sensitive code.
669 /// The delayed check only considers the value of the pointer that was dereferenced, not the
670 /// intermediate values used during the computation of the final result. For example,
671 /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the
672 /// allocated object and then re-entering it later is permitted.
674 /// [`sub`]: #method.sub
675 /// [allocated object]: crate::ptr#allocated-object
682 /// // Iterate using a raw pointer in increments of two elements (backwards)
683 /// let data = [1u8, 2, 3, 4, 5];
684 /// let mut ptr: *const u8 = data.as_ptr();
685 /// let start_rounded_down = ptr.wrapping_sub(2);
686 /// ptr = ptr.wrapping_add(4);
688 /// // This loop prints "5, 3, 1, "
689 /// while ptr != start_rounded_down {
691 /// print!("{}, ", *ptr);
693 /// ptr = ptr.wrapping_sub(step);
696 #[stable(feature = "pointer_methods", since = "1.26.0")]
697 #[must_use = "returns a new pointer rather than modifying its argument"]
698 #[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
700 pub const fn wrapping_sub(self, count: usize) -> Self
704 self.wrapping_offset((count as isize).wrapping_neg())
707 /// Sets the pointer value to `ptr`.
709 /// In case `self` is a (fat) pointer to an unsized type, this operation
710 /// will only affect the pointer part, whereas for (thin) pointers to
711 /// sized types, this has the same effect as a simple assignment.
713 /// The resulting pointer will have provenance of `val`, i.e., for a fat
714 /// pointer, this operation is semantically the same as creating a new
715 /// fat pointer with the data pointer value of `val` but the metadata of
720 /// This function is primarily useful for allowing byte-wise pointer
721 /// arithmetic on potentially fat pointers:
724 /// #![feature(set_ptr_value)]
725 /// # use core::fmt::Debug;
726 /// let arr: [i32; 3] = [1, 2, 3];
727 /// let mut ptr = arr.as_ptr() as *const dyn Debug;
728 /// let thin = ptr as *const u8;
730 /// ptr = ptr.set_ptr_value(thin.add(8));
731 /// # assert_eq!(*(ptr as *const i32), 3);
732 /// println!("{:?}", &*ptr); // will print "3"
735 #[unstable(feature = "set_ptr_value", issue = "75091")]
736 #[must_use = "returns a new pointer rather than modifying its argument"]
738 pub fn set_ptr_value(mut self, val: *const u8) -> Self {
739 let thin = &mut self as *mut *const T as *mut *const u8;
740 // SAFETY: In case of a thin pointer, this operations is identical
741 // to a simple assignment. In case of a fat pointer, with the current
742 // fat pointer layout implementation, the first field of such a
743 // pointer is always the data pointer, which is likewise assigned.
744 unsafe { *thin = val };
748 /// Reads the value from `self` without moving it. This leaves the
749 /// memory in `self` unchanged.
751 /// See [`ptr::read`] for safety concerns and examples.
753 /// [`ptr::read`]: crate::ptr::read()
754 #[stable(feature = "pointer_methods", since = "1.26.0")]
755 #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
757 pub const unsafe fn read(self) -> T
761 // SAFETY: the caller must uphold the safety contract for `read`.
762 unsafe { read(self) }
765 /// Performs a volatile read of the value from `self` without moving it. This
766 /// leaves the memory in `self` unchanged.
768 /// Volatile operations are intended to act on I/O memory, and are guaranteed
769 /// to not be elided or reordered by the compiler across other volatile
772 /// See [`ptr::read_volatile`] for safety concerns and examples.
774 /// [`ptr::read_volatile`]: crate::ptr::read_volatile()
775 #[stable(feature = "pointer_methods", since = "1.26.0")]
777 pub unsafe fn read_volatile(self) -> T
781 // SAFETY: the caller must uphold the safety contract for `read_volatile`.
782 unsafe { read_volatile(self) }
785 /// Reads the value from `self` without moving it. This leaves the
786 /// memory in `self` unchanged.
788 /// Unlike `read`, the pointer may be unaligned.
790 /// See [`ptr::read_unaligned`] for safety concerns and examples.
792 /// [`ptr::read_unaligned`]: crate::ptr::read_unaligned()
793 #[stable(feature = "pointer_methods", since = "1.26.0")]
794 #[rustc_const_unstable(feature = "const_ptr_read", issue = "80377")]
796 pub const unsafe fn read_unaligned(self) -> T
800 // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
801 unsafe { read_unaligned(self) }
804 /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
805 /// and destination may overlap.
807 /// NOTE: this has the *same* argument order as [`ptr::copy`].
809 /// See [`ptr::copy`] for safety concerns and examples.
811 /// [`ptr::copy`]: crate::ptr::copy()
812 #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
813 #[stable(feature = "pointer_methods", since = "1.26.0")]
815 pub const unsafe fn copy_to(self, dest: *mut T, count: usize)
819 // SAFETY: the caller must uphold the safety contract for `copy`.
820 unsafe { copy(self, dest, count) }
823 /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
824 /// and destination may *not* overlap.
826 /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
828 /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
830 /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
831 #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
832 #[stable(feature = "pointer_methods", since = "1.26.0")]
834 pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize)
838 // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
839 unsafe { copy_nonoverlapping(self, dest, count) }
842 /// Computes the offset that needs to be applied to the pointer in order to make it aligned to
845 /// If it is not possible to align the pointer, the implementation returns
846 /// `usize::MAX`. It is permissible for the implementation to *always*
847 /// return `usize::MAX`. Only your algorithm's performance can depend
848 /// on getting a usable offset here, not its correctness.
850 /// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
851 /// used with the `wrapping_add` method.
853 /// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
854 /// beyond the allocation that the pointer points into. It is up to the caller to ensure that
855 /// the returned offset is correct in all terms other than alignment.
859 /// The function panics if `align` is not a power-of-two.
863 /// Accessing adjacent `u8` as `u16`
866 /// # fn foo(n: usize) {
867 /// # use std::mem::align_of;
869 /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
870 /// let ptr = x.as_ptr().add(n) as *const u8;
871 /// let offset = ptr.align_offset(align_of::<u16>());
872 /// if offset < x.len() - n - 1 {
873 /// let u16_ptr = ptr.add(offset) as *const u16;
874 /// assert_ne!(*u16_ptr, 500);
876 /// // while the pointer can be aligned via `offset`, it would point
877 /// // outside the allocation
881 #[stable(feature = "align_offset", since = "1.36.0")]
882 #[rustc_const_unstable(feature = "const_align_offset", issue = "90962")]
883 pub const fn align_offset(self, align: usize) -> usize
887 if !align.is_power_of_two() {
888 panic!("align_offset: align is not a power-of-two");
891 fn rt_impl<T>(p: *const T, align: usize) -> usize {
892 // SAFETY: `align` has been checked to be a power of 2 above
893 unsafe { align_offset(p, align) }
896 const fn ctfe_impl<T>(_: *const T, _: usize) -> usize {
901 // It is permisseble for `align_offset` to always return `usize::MAX`,
902 // algorithm correctness can not depend on `align_offset` returning non-max values.
904 // As such the behaviour can't change after replacing `align_offset` with `usize::MAX`, only performance can.
905 unsafe { intrinsics::const_eval_select((self, align), ctfe_impl, rt_impl) }
909 #[lang = "const_slice_ptr"]
911 /// Returns the length of a raw slice.
913 /// The returned value is the number of **elements**, not the number of bytes.
915 /// This function is safe, even when the raw slice cannot be cast to a slice
916 /// reference because the pointer is null or unaligned.
921 /// #![feature(slice_ptr_len)]
925 /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
926 /// assert_eq!(slice.len(), 3);
929 #[unstable(feature = "slice_ptr_len", issue = "71146")]
930 #[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
931 pub const fn len(self) -> usize {
935 /// Returns a raw pointer to the slice's buffer.
937 /// This is equivalent to casting `self` to `*const T`, but more type-safe.
942 /// #![feature(slice_ptr_get)]
945 /// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
946 /// assert_eq!(slice.as_ptr(), 0 as *const i8);
949 #[unstable(feature = "slice_ptr_get", issue = "74265")]
950 #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
951 pub const fn as_ptr(self) -> *const T {
955 /// Returns a raw pointer to an element or subslice, without doing bounds
958 /// Calling this method with an out-of-bounds index or when `self` is not dereferencable
959 /// is *[undefined behavior]* even if the resulting pointer is not used.
961 /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
966 /// #![feature(slice_ptr_get)]
968 /// let x = &[1, 2, 4] as *const [i32];
971 /// assert_eq!(x.get_unchecked(1), x.as_ptr().add(1));
974 #[unstable(feature = "slice_ptr_get", issue = "74265")]
976 pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
980 // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
981 unsafe { index.get_unchecked(self) }
984 /// Returns `None` if the pointer is null, or else returns a shared slice to
985 /// the value wrapped in `Some`. In contrast to [`as_ref`], this does not require
986 /// that the value has to be initialized.
988 /// [`as_ref`]: #method.as_ref
992 /// When calling this method, you have to ensure that *either* the pointer is null *or*
993 /// all of the following is true:
995 /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
996 /// and it must be properly aligned. This means in particular:
998 /// * The entire memory range of this slice must be contained within a single [allocated object]!
999 /// Slices can never span across multiple allocated objects.
1001 /// * The pointer must be aligned even for zero-length slices. One
1002 /// reason for this is that enum layout optimizations may rely on references
1003 /// (including slices of any length) being aligned and non-null to distinguish
1004 /// them from other data. You can obtain a pointer that is usable as `data`
1005 /// for zero-length slices using [`NonNull::dangling()`].
1007 /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
1008 /// See the safety documentation of [`pointer::offset`].
1010 /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
1011 /// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
1012 /// In particular, for the duration of this lifetime, the memory the pointer points to must
1013 /// not get mutated (except inside `UnsafeCell`).
1015 /// This applies even if the result of this method is unused!
1017 /// See also [`slice::from_raw_parts`][].
1019 /// [valid]: crate::ptr#safety
1020 /// [allocated object]: crate::ptr#allocated-object
1022 #[unstable(feature = "ptr_as_uninit", issue = "75402")]
1023 pub unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
1027 // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
1028 Some(unsafe { slice::from_raw_parts(self as *const MaybeUninit<T>, self.len()) })
1033 // Equality for pointers
1034 #[stable(feature = "rust1", since = "1.0.0")]
1035 impl<T: ?Sized> PartialEq for *const T {
1037 fn eq(&self, other: &*const T) -> bool {
1042 #[stable(feature = "rust1", since = "1.0.0")]
1043 impl<T: ?Sized> Eq for *const T {}
1045 // Comparison for pointers
1046 #[stable(feature = "rust1", since = "1.0.0")]
1047 impl<T: ?Sized> Ord for *const T {
1049 fn cmp(&self, other: &*const T) -> Ordering {
1052 } else if self == other {
1060 #[stable(feature = "rust1", since = "1.0.0")]
1061 impl<T: ?Sized> PartialOrd for *const T {
1063 fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
1064 Some(self.cmp(other))
1068 fn lt(&self, other: &*const T) -> bool {
1073 fn le(&self, other: &*const T) -> bool {
1078 fn gt(&self, other: &*const T) -> bool {
1083 fn ge(&self, other: &*const T) -> bool {