1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // FIXME: talk about offset, copy_memory, copy_nonoverlapping_memory
13 //! Operations on unsafe pointers, `*const T`, and `*mut T`.
15 //! Working with unsafe pointers in Rust is uncommon,
16 //! typically limited to a few patterns.
18 //! Use the [`null` function](fn.null.html) to create null pointers,
19 //! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
20 //! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
21 //! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
22 //! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
23 //! work everywhere. The `RawPtr` also defines the `offset` method,
26 //! # Common ways to create unsafe pointers
28 //! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
31 //! let my_num: int = 10;
32 //! let my_num_ptr: *const int = &my_num;
33 //! let mut my_speed: int = 88;
34 //! let my_speed_ptr: *mut int = &mut my_speed;
37 //! This does not take ownership of the original allocation
38 //! and requires no resource management later,
39 //! but you must not use the pointer after its lifetime.
41 //! ## 2. Transmute an owned box (`Box<T>`).
43 //! The `transmute` function takes, by value, whatever it's given
44 //! and returns it as whatever type is requested, as long as the
45 //! types are the same size. Because `Box<T>` and `*mut T` have the same
46 //! representation they can be trivially,
47 //! though unsafely, transformed from one type to the other.
53 //! let my_num: Box<int> = box 10;
54 //! let my_num: *const int = mem::transmute(my_num);
55 //! let my_speed: Box<int> = box 88;
56 //! let my_speed: *mut int = mem::transmute(my_speed);
58 //! // By taking ownership of the original `Box<T>` though
59 //! // we are obligated to transmute it back later to be destroyed.
60 //! drop(mem::transmute::<_, Box<int>>(my_speed));
61 //! drop(mem::transmute::<_, Box<int>>(my_num));
65 //! Note that here the call to `drop` is for clarity - it indicates
66 //! that we are done with the given value and it should be destroyed.
68 //! ## 3. Get it from C.
71 //! extern crate libc;
77 //! let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
78 //! if my_num.is_null() {
79 //! fail!("failed to allocate memory");
81 //! libc::free(my_num as *mut libc::c_void);
86 //! Usually you wouldn't literally use `malloc` and `free` from Rust,
87 //! but C APIs hand out a lot of pointers generally, so are a common source
88 //! of unsafe pointers in Rust.
94 use option::{Some, None, Option};
96 use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
98 pub use intrinsics::copy_memory;
99 pub use intrinsics::copy_nonoverlapping_memory;
100 pub use intrinsics::set_memory;
102 /// Create a null pointer.
109 /// let p: *const int = ptr::null();
110 /// assert!(p.is_null());
113 #[unstable = "may need a different name after pending changes to pointer types"]
114 pub fn null<T>() -> *const T { 0 as *const T }
116 /// Create an unsafe mutable null pointer.
123 /// let p: *mut int = ptr::mut_null();
124 /// assert!(p.is_null());
127 #[unstable = "may need a different name after pending changes to pointer types"]
128 pub fn mut_null<T>() -> *mut T { 0 as *mut T }
130 /// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
132 #[experimental = "uncertain about naming and semantics"]
133 #[allow(experimental)]
134 pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
135 set_memory(dst, 0, count);
138 /// Swap the values at two mutable locations of the same type, without
139 /// deinitialising either. They may overlap.
142 pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
143 // Give ourselves some scratch space to work with
144 let mut tmp: T = mem::uninitialized();
145 let t: *mut T = &mut tmp;
148 copy_nonoverlapping_memory(t, &*x, 1);
149 copy_memory(x, &*y, 1); // `x` and `y` may overlap
150 copy_nonoverlapping_memory(y, &*t, 1);
152 // y and t now point to the same thing, but we need to completely forget `tmp`
153 // because it's no longer relevant.
157 /// Replace the value at a mutable location with a new one, returning the old
158 /// value, without deinitialising either.
161 pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
162 mem::swap(mem::transmute(dest), &mut src); // cannot overlap
166 /// Reads the value from `*src` and returns it.
169 pub unsafe fn read<T>(src: *const T) -> T {
170 let mut tmp: T = mem::uninitialized();
171 copy_nonoverlapping_memory(&mut tmp, src, 1);
175 /// Reads the value from `*src` and nulls it out.
176 /// This currently prevents destructors from executing.
179 #[allow(experimental)]
180 pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
181 // Copy the data out from `dest`:
182 let tmp = read(&*dest);
184 // Now zero out `dest`:
185 zero_memory(dest, 1);
190 /// Unsafely overwrite a memory location with the given value without destroying
193 /// This operation is unsafe because it does not destroy the previous value
194 /// contained at the location `dst`. This could leak allocations or resources,
195 /// so care must be taken to previously deallocate the value at `dst`.
198 pub unsafe fn write<T>(dst: *mut T, src: T) {
199 intrinsics::move_val_init(&mut *dst, src)
202 /// Given a *const *const T (pointer to an array of pointers),
203 /// iterate through each *const T, up to the provided `len`,
204 /// passing to the provided callback function
205 #[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
206 pub unsafe fn array_each_with_len<T>(arr: *const *const T, len: uint,
209 fail!("ptr::array_each_with_len failure: arr input is null pointer");
211 //let start_ptr = *arr;
212 for e in range(0, len) {
213 let n = arr.offset(e as int);
218 /// Given a null-pointer-terminated *const *const T (pointer to
219 /// an array of pointers), iterate through each *const T,
220 /// passing to the provided callback function
224 /// This will only work with a null-terminated
226 #[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
228 pub unsafe fn array_each<T>(arr: *const *const T, cb: |*const T|) {
230 fail!("ptr::array_each_with_len failure: arr input is null pointer");
232 let len = buf_len(arr);
233 array_each_with_len(arr, len, cb);
236 /// Return the offset of the first null pointer in `buf`.
238 #[deprecated = "use a loop and RawPtr::offset"]
240 pub unsafe fn buf_len<T>(buf: *const *const T) -> uint {
241 position(buf, |i| *i == null())
244 /// Return the first offset `i` such that `f(buf[i]) == true`.
246 #[deprecated = "old-style iteration. use a loop and RawPtr::offset"]
247 pub unsafe fn position<T>(buf: *const T, f: |&T| -> bool) -> uint {
250 if f(&(*buf.offset(i as int))) { return i; }
255 /// Methods on raw pointers
256 pub trait RawPtr<T> {
257 /// Returns the null pointer.
260 /// Returns true if the pointer is equal to the null pointer.
261 fn is_null(&self) -> bool;
263 /// Returns true if the pointer is not equal to the null pointer.
264 fn is_not_null(&self) -> bool { !self.is_null() }
266 /// Returns the value of this pointer (ie, the address it points to)
267 fn to_uint(&self) -> uint;
269 /// Returns `None` if the pointer is null, or else returns a reference to the
270 /// value wrapped in `Some`.
274 /// While this method and its mutable counterpart are useful for null-safety,
275 /// it is important to note that this is still an unsafe operation because
276 /// the returned value could be pointing to invalid memory.
277 unsafe fn as_ref<'a>(&self) -> Option<&'a T>;
279 /// A synonym for `as_ref`, except with incorrect lifetime semantics
280 #[deprecated="Use `as_ref` instead"]
281 unsafe fn to_option<'a>(&'a self) -> Option<&'a T> {
282 mem::transmute(self.as_ref())
285 /// Calculates the offset from a pointer. The offset *must* be in-bounds of
286 /// the object, or one-byte-past-the-end. `count` is in units of T; e.g. a
287 /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
288 unsafe fn offset(self, count: int) -> Self;
291 /// Methods on mutable raw pointers
292 pub trait RawMutPtr<T>{
293 /// Returns `None` if the pointer is null, or else returns a mutable reference
294 /// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because
295 /// it cannot verify the validity of the returned pointer.
296 unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>;
299 impl<T> RawPtr<T> for *const T {
301 fn null() -> *const T { null() }
304 fn is_null(&self) -> bool { *self == RawPtr::null() }
307 fn to_uint(&self) -> uint { *self as uint }
310 unsafe fn offset(self, count: int) -> *const T {
311 intrinsics::offset(self, count)
315 unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
324 impl<T> RawPtr<T> for *mut T {
326 fn null() -> *mut T { mut_null() }
329 fn is_null(&self) -> bool { *self == RawPtr::null() }
332 fn to_uint(&self) -> uint { *self as uint }
335 unsafe fn offset(self, count: int) -> *mut T {
336 intrinsics::offset(self as *const T, count) as *mut T
340 unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
349 impl<T> RawMutPtr<T> for *mut T {
351 unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
360 // Equality for pointers
361 impl<T> PartialEq for *const T {
363 fn eq(&self, other: &*const T) -> bool {
367 fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
370 impl<T> Eq for *const T {}
372 impl<T> PartialEq for *mut T {
374 fn eq(&self, other: &*mut T) -> bool {
378 fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
381 impl<T> Eq for *mut T {}
383 // Equivalence for pointers
384 impl<T> Equiv<*mut T> for *const T {
385 fn equiv(&self, other: &*mut T) -> bool {
386 self.to_uint() == other.to_uint()
390 impl<T> Equiv<*const T> for *mut T {
391 fn equiv(&self, other: &*const T) -> bool {
392 self.to_uint() == other.to_uint()
396 impl<T> Clone for *const T {
398 fn clone(&self) -> *const T {
403 impl<T> Clone for *mut T {
405 fn clone(&self) -> *mut T {
410 // Equality for extern "C" fn pointers
411 mod externfnpointers {
415 impl<_R> PartialEq for extern "C" fn() -> _R {
417 fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
418 let self_: *const () = unsafe { mem::transmute(*self) };
419 let other_: *const () = unsafe { mem::transmute(*other) };
423 macro_rules! fnptreq(
425 impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R {
427 fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
428 let self_: *const () = unsafe { mem::transmute(*self) };
430 let other_: *const () = unsafe { mem::transmute(*other) };
443 // Comparison for pointers
444 impl<T> PartialOrd for *const T {
446 fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
449 } else if self == other {
457 fn lt(&self, other: &*const T) -> bool { *self < *other }
460 fn le(&self, other: &*const T) -> bool { *self <= *other }
463 fn gt(&self, other: &*const T) -> bool { *self > *other }
466 fn ge(&self, other: &*const T) -> bool { *self >= *other }
469 impl<T> PartialOrd for *mut T {
471 fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
474 } else if self == other {
482 fn lt(&self, other: &*mut T) -> bool { *self < *other }
485 fn le(&self, other: &*mut T) -> bool { *self <= *other }
488 fn gt(&self, other: &*mut T) -> bool { *self > *other }
491 fn ge(&self, other: &*mut T) -> bool { *self >= *other }