// FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
-//! Raw, unsafe pointers, `*const T`, and `*mut T`
+//! Raw, unsafe pointers, `*const T`, and `*mut T`.
//!
-//! *[See also the pointer primitive types](../primitive.pointer.html).*
+//! *[See also the pointer primitive types](../../std/primitive.pointer.html).*
#![stable(feature = "rust1", since = "1.0.0")]
///
/// Volatile operations are intended to act on I/O memory, and are guaranteed
/// to not be elided or reordered by the compiler across other volatile
-/// operations. See the LLVM documentation on [[volatile]].
+/// operations.
///
-/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses
+/// # Notes
+///
+/// Rust does not currently have a rigorously and formally defined memory model,
+/// so the precise semantics of what "volatile" means here is subject to change
+/// over time. That being said, the semantics will almost always end up pretty
+/// similar to [C11's definition of volatile][c11].
+///
+/// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
///
/// # Safety
///
/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
/// because it will attempt to drop the value previously at `*src`.
#[inline]
-#[unstable(feature = "volatile", reason = "recently added", issue = "31756")]
+#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn read_volatile<T>(src: *const T) -> T {
intrinsics::volatile_load(src)
}
///
/// Volatile operations are intended to act on I/O memory, and are guaranteed
/// to not be elided or reordered by the compiler across other volatile
-/// operations. See the LLVM documentation on [[volatile]].
+/// operations.
+///
+/// # Notes
+///
+/// Rust does not currently have a rigorously and formally defined memory model,
+/// so the precise semantics of what "volatile" means here is subject to change
+/// over time. That being said, the semantics will almost always end up pretty
+/// similar to [C11's definition of volatile][c11].
///
-/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses
+/// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
///
/// # Safety
///
/// This is appropriate for initializing uninitialized memory, or overwriting
/// memory that has previously been `read` from.
#[inline]
-#[unstable(feature = "volatile", reason = "recently added", issue = "31756")]
+#[stable(feature = "volatile", since = "1.9.0")]
pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
intrinsics::volatile_store(dst, src);
}
#[lang = "const_ptr"]
impl<T: ?Sized> *const T {
/// Returns true if the pointer is null.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s: &str = "Follow the rabbit";
+ /// let ptr: *const u8 = s.as_ptr();
+ /// assert!(!ptr.is_null());
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_null(self) -> bool where T: Sized {
/// null-safety, it is important to note that this is still an unsafe
/// operation because the returned value could be pointing to invalid
/// memory.
- #[unstable(feature = "ptr_as_ref",
- reason = "Option is not clearly the right return type, and we \
- may want to tie the return lifetime to a borrow of \
- the raw pointer",
- issue = "27780")]
+ ///
+ /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
+ /// not necessarily reflect the actual lifetime of the data.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```ignore
+ /// let val: *const u8 = &10u8 as *const u8;
+ ///
+ /// unsafe {
+ /// if let Some(val_back) = val.as_ref() {
+ /// println!("We got back the value: {}!", val_back);
+ /// }
+ /// }
+ /// ```
+ #[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
- pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized {
+ pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
if self.is_null() {
None
} else {
- Some(&**self)
+ Some(&*self)
}
}
/// byte past the end of an allocated object. If either pointer is out of
/// bounds or arithmetic overflow occurs then
/// any further use of the returned value will result in undefined behavior.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let s: &str = "123";
+ /// let ptr: *const u8 = s.as_ptr();
+ ///
+ /// unsafe {
+ /// println!("{}", *ptr.offset(1) as char);
+ /// println!("{}", *ptr.offset(2) as char);
+ /// }
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
#[lang = "mut_ptr"]
impl<T: ?Sized> *mut T {
/// Returns true if the pointer is null.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let mut s = [1, 2, 3];
+ /// let ptr: *mut u32 = s.as_mut_ptr();
+ /// assert!(!ptr.is_null());
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_null(self) -> bool where T: Sized {
/// null-safety, it is important to note that this is still an unsafe
/// operation because the returned value could be pointing to invalid
/// memory.
- #[unstable(feature = "ptr_as_ref",
- reason = "Option is not clearly the right return type, and we \
- may want to tie the return lifetime to a borrow of \
- the raw pointer",
- issue = "27780")]
+ ///
+ /// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
+ /// not necessarily reflect the actual lifetime of the data.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```ignore
+ /// let val: *mut u8 = &mut 10u8 as *mut u8;
+ ///
+ /// unsafe {
+ /// if let Some(val_back) = val.as_ref() {
+ /// println!("We got back the value: {}!", val_back);
+ /// }
+ /// }
+ /// ```
+ #[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
- pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> where T: Sized {
+ pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
if self.is_null() {
None
} else {
- Some(&**self)
+ Some(&*self)
}
}
/// The offset must be in-bounds of the object, or one-byte-past-the-end.
/// Otherwise `offset` invokes Undefined Behavior, regardless of whether
/// the pointer is used.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let mut s = [1, 2, 3];
+ /// let ptr: *mut u32 = s.as_mut_ptr();
+ ///
+ /// unsafe {
+ /// println!("{}", *ptr.offset(1));
+ /// println!("{}", *ptr.offset(2));
+ /// }
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
/// # Safety
///
/// As with `as_ref`, this is unsafe because it cannot verify the validity
- /// of the returned pointer.
- #[unstable(feature = "ptr_as_ref",
- reason = "return value does not necessarily convey all possible \
- information",
- issue = "27780")]
+ /// of the returned pointer, nor can it ensure that the lifetime `'a`
+ /// returned is indeed a valid lifetime for the contained data.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// let mut s = [1, 2, 3];
+ /// let ptr: *mut u32 = s.as_mut_ptr();
+ /// ```
+ #[stable(feature = "ptr_as_ref", since = "1.9.0")]
#[inline]
- pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> where T: Sized {
+ pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> where T: Sized {
if self.is_null() {
None
} else {
- Some(&mut **self)
+ Some(&mut *self)
}
}
}
/// modified without a unique path to the `Unique` reference. Useful
/// for building abstractions like `Vec<T>` or `Box<T>`, which
/// internally use raw pointers to manage the memory that they own.
+#[allow(missing_debug_implementations)]
#[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
issue = "27730")]
pub struct Unique<T: ?Sized> {
/// of this wrapper has shared ownership of the referent. Useful for
/// building abstractions like `Rc<T>` or `Arc<T>`, which internally
/// use raw pointers to manage the memory that they own.
+#[allow(missing_debug_implementations)]
#[unstable(feature = "shared", reason = "needs an RFC to flesh out design",
issue = "27730")]
pub struct Shared<T: ?Sized> {