1 // Copyright 2012-2013 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 //! Conveniences for working with unsafe pointers, the `*T`, and `*mut T` types.
13 //! Working with unsafe pointers in Rust is fairly uncommon,
14 //! and often limited to some narrow use cases: holding
15 //! an unsafe pointer when safe pointers are unsuitable;
16 //! checking for null; and converting back to safe pointers.
17 //! As a result, there is not yet an abundance of library code
18 //! for working with unsafe pointers, and in particular,
19 //! since pointer math is fairly uncommon in Rust, it is not
20 //! all that convenient.
22 //! Use the [`null` function](fn.null.html) to create null pointers,
23 //! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
24 //! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
25 //! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
26 //! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
29 //! # Common ways to create unsafe pointers
31 //! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
34 //! let my_num: int = 10;
35 //! let my_num_ptr: *int = &my_num;
36 //! let mut my_speed: int = 88;
37 //! let my_speed_ptr: *mut int = &mut my_speed;
40 //! This does not take ownership of the original allocation
41 //! and requires no resource management later,
42 //! but you must not use the pointer after its lifetime.
44 //! ## 2. Transmute an owned box (`Box<T>`).
46 //! The `transmute` function takes, by value, whatever it's given
47 //! and returns it as whatever type is requested, as long as the
48 //! types are the same size. Because `Box<T>` and `*T` have the same
49 //! representation they can be trivially,
50 //! though unsafely, transformed from one type to the other.
56 //! let my_num: Box<int> = box 10;
57 //! let my_num: *int = cast::transmute(my_num);
58 //! let my_speed: Box<int> = box 88;
59 //! let my_speed: *mut int = cast::transmute(my_speed);
61 //! // By taking ownership of the original `Box<T>` though
62 //! // we are obligated to transmute it back later to be destroyed.
63 //! drop(cast::transmute::<_, Box<int>>(my_speed));
64 //! drop(cast::transmute::<_, Box<int>>(my_num));
68 //! Note that here the call to `drop` is for clarity - it indicates
69 //! that we are done with the given value and it should be destroyed.
71 //! ## 3. Get it from C.
74 //! extern crate libc;
80 //! let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
81 //! if my_num.is_null() {
82 //! fail!("failed to allocate memory");
84 //! libc::free(my_num as *mut libc::c_void);
89 //! Usually you wouldn't literally use `malloc` and `free` from Rust,
90 //! but C APIs hand out a lot of pointers generally, so are a common source
91 //! of unsafe pointers in Rust.
97 use iter::{range, Iterator};
99 use option::{Option, Some, None};
102 #[cfg(not(test))] use cmp::{Eq, TotalEq, Ord};
104 /// Return the offset of the first null pointer in `buf`.
106 pub unsafe fn buf_len<T>(buf: **T) -> uint {
107 position(buf, |i| *i == null())
110 impl<T> Clone for *T {
112 fn clone(&self) -> *T {
117 impl<T> Clone for *mut T {
119 fn clone(&self) -> *mut T {
124 /// Return the first offset `i` such that `f(buf[i]) == true`.
126 pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
129 if f(&(*buf.offset(i as int))) { return i; }
134 /// Create a null pointer.
141 /// let p: *int = ptr::null();
142 /// assert!(p.is_null());
145 pub fn null<T>() -> *T { 0 as *T }
147 /// Create an unsafe mutable null pointer.
154 /// let p: *mut int = ptr::mut_null();
155 /// assert!(p.is_null());
158 pub fn mut_null<T>() -> *mut T { 0 as *mut T }
160 /// Copies data from one location to another.
162 /// Copies `count` elements (not bytes) from `src` to `dst`. The source
163 /// and destination may overlap.
165 /// `copy_memory` is semantically equivalent to C's `memmove`.
169 /// Efficiently create a Rust vector from an unsafe buffer:
174 /// unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> Vec<T> {
175 /// let mut dst = Vec::with_capacity(elts);
176 /// dst.set_len(elts);
177 /// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
183 pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
184 intrinsics::copy_memory(dst, src, count)
187 /// Copies data from one location to another.
189 /// Copies `count` elements (not bytes) from `src` to `dst`. The source
190 /// and destination may *not* overlap.
192 /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
196 /// A safe swap function:
203 /// fn swap<T>(x: &mut T, y: &mut T) {
205 /// // Give ourselves some scratch space to work with
206 /// let mut t: T = mem::uninit();
208 /// // Perform the swap, `&mut` pointers never alias
209 /// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
210 /// ptr::copy_nonoverlapping_memory(x, &*y, 1);
211 /// ptr::copy_nonoverlapping_memory(y, &t, 1);
213 /// // y and t now point to the same thing, but we need to completely forget `tmp`
214 /// // because it's no longer relevant.
222 /// If the source and destination overlap then the behavior of this
223 /// function is undefined.
225 pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
228 intrinsics::copy_nonoverlapping_memory(dst, src, count)
231 /// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
232 /// bytes of memory starting at `dst` to `c`.
234 pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
235 intrinsics::set_memory(dst, c, count)
238 /// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
240 pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
241 set_memory(dst, 0, count);
244 /// Swap the values at two mutable locations of the same type, without
245 /// deinitialising either. They may overlap.
247 pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
248 // Give ourselves some scratch space to work with
249 let mut tmp: T = mem::uninit();
250 let t: *mut T = &mut tmp;
253 copy_nonoverlapping_memory(t, &*x, 1);
254 copy_memory(x, &*y, 1); // `x` and `y` may overlap
255 copy_nonoverlapping_memory(y, &*t, 1);
257 // y and t now point to the same thing, but we need to completely forget `tmp`
258 // because it's no longer relevant.
262 /// Replace the value at a mutable location with a new one, returning the old
263 /// value, without deinitialising either.
265 pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
266 mem::swap(cast::transmute(dest), &mut src); // cannot overlap
270 /// Reads the value from `*src` and returns it.
272 pub unsafe fn read<T>(src: *T) -> T {
273 let mut tmp: T = mem::uninit();
274 copy_nonoverlapping_memory(&mut tmp, src, 1);
278 /// Reads the value from `*src` and nulls it out.
279 /// This currently prevents destructors from executing.
281 pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
282 // Copy the data out from `dest`:
283 let tmp = read(&*dest);
285 // Now zero out `dest`:
286 zero_memory(dest, 1);
291 /// Given a **T (pointer to an array of pointers),
292 /// iterate through each *T, up to the provided `len`,
293 /// passing to the provided callback function
294 pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
296 fail!("ptr::array_each_with_len failure: arr input is null pointer");
298 //let start_ptr = *arr;
299 for e in range(0, len) {
300 let n = arr.offset(e as int);
305 /// Given a null-pointer-terminated **T (pointer to
306 /// an array of pointers), iterate through each *T,
307 /// passing to the provided callback function
311 /// This will only work with a null-terminated
313 pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
315 fail!("ptr::array_each_with_len failure: arr input is null pointer");
317 let len = buf_len(arr);
318 array_each_with_len(arr, len, cb);
321 /// Extension methods for raw pointers.
322 pub trait RawPtr<T> {
323 /// Returns the null pointer.
325 /// Returns true if the pointer is equal to the null pointer.
326 fn is_null(&self) -> bool;
327 /// Returns true if the pointer is not equal to the null pointer.
328 fn is_not_null(&self) -> bool { !self.is_null() }
329 /// Returns the value of this pointer (ie, the address it points to)
330 fn to_uint(&self) -> uint;
331 /// Returns `None` if the pointer is null, or else returns the value wrapped
336 /// While this method is useful for null-safety, it is important to note
337 /// that this is still an unsafe operation because the returned value could
338 /// be pointing to invalid memory.
339 unsafe fn to_option(&self) -> Option<&T>;
340 /// Calculates the offset from a pointer. The offset *must* be in-bounds of
341 /// the object, or one-byte-past-the-end. `count` is in units of T; e.g. a
342 /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
343 unsafe fn offset(self, count: int) -> Self;
346 impl<T> RawPtr<T> for *T {
348 fn null() -> *T { null() }
351 fn is_null(&self) -> bool { *self == RawPtr::null() }
354 fn to_uint(&self) -> uint { *self as uint }
357 unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
360 unsafe fn to_option(&self) -> Option<&T> {
364 Some(cast::transmute(*self))
369 impl<T> RawPtr<T> for *mut T {
371 fn null() -> *mut T { mut_null() }
374 fn is_null(&self) -> bool { *self == RawPtr::null() }
377 fn to_uint(&self) -> uint { *self as uint }
380 unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }
383 unsafe fn to_option(&self) -> Option<&T> {
387 Some(cast::transmute(*self))
392 // Equality for pointers
396 fn eq(&self, other: &*T) -> bool {
400 fn ne(&self, other: &*T) -> bool { !self.eq(other) }
404 impl<T> TotalEq for *T {}
407 impl<T> Eq for *mut T {
409 fn eq(&self, other: &*mut T) -> bool {
413 fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
417 impl<T> TotalEq for *mut T {}
419 // Equivalence for pointers
421 impl<T> Equiv<*mut T> for *T {
422 fn equiv(&self, other: &*mut T) -> bool {
423 self.to_uint() == other.to_uint()
428 impl<T> Equiv<*T> for *mut T {
429 fn equiv(&self, other: &*T) -> bool {
430 self.to_uint() == other.to_uint()
434 // Equality for extern "C" fn pointers
436 mod externfnpointers {
440 impl<_R> Eq for extern "C" fn() -> _R {
442 fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
443 let self_: *() = unsafe { cast::transmute(*self) };
444 let other_: *() = unsafe { cast::transmute(*other) };
448 fn ne(&self, other: &extern "C" fn() -> _R) -> bool {
452 macro_rules! fnptreq(
454 impl<_R,$($p),*> Eq for extern "C" fn($($p),*) -> _R {
456 fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
457 let self_: *() = unsafe { cast::transmute(*self) };
458 let other_: *() = unsafe { cast::transmute(*other) };
462 fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
475 // Comparison for pointers
479 fn lt(&self, other: &*T) -> bool {
483 fn le(&self, other: &*T) -> bool {
487 fn ge(&self, other: &*T) -> bool {
491 fn gt(&self, other: &*T) -> bool {
497 impl<T> Ord for *mut T {
499 fn lt(&self, other: &*mut T) -> bool {
503 fn le(&self, other: &*mut T) -> bool {
507 fn ge(&self, other: &*mut T) -> bool {
511 fn gt(&self, other: &*mut T) -> bool {
525 use slice::{ImmutableVector, MutableVector};
534 let mut p = Pair {fst: 10, snd: 20};
535 let pptr: *mut Pair = &mut p;
536 let iptr: *mut int = cast::transmute(pptr);
537 assert_eq!(*iptr, 10);
539 assert_eq!(*iptr, 30);
540 assert_eq!(p.fst, 30);
542 *pptr = Pair {fst: 50, snd: 60};
543 assert_eq!(*iptr, 50);
544 assert_eq!(p.fst, 50);
545 assert_eq!(p.snd, 60);
547 let v0 = box [32000u16, 32001u16, 32002u16];
548 let mut v1 = box [0u16, 0u16, 0u16];
550 copy_memory(v1.as_mut_ptr().offset(1),
551 v0.as_ptr().offset(1), 1);
552 assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
553 copy_memory(v1.as_mut_ptr(),
554 v0.as_ptr().offset(2), 1);
555 assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
557 copy_memory(v1.as_mut_ptr().offset(2),
559 assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
568 "hello".with_c_str(|p| {
570 assert!(2u == position(p, |c| *c == 'l' as c_char));
571 assert!(4u == position(p, |c| *c == 'o' as c_char));
572 assert!(5u == position(p, |c| *c == 0 as c_char));
579 "hello".with_c_str(|p0| {
580 "there".with_c_str(|p1| {
581 "thing".with_c_str(|p2| {
582 let v = box [p0, p1, p2, null()];
584 assert_eq!(buf_len(v.as_ptr()), 3u);
593 let p: *int = null();
594 assert!(p.is_null());
595 assert!(!p.is_not_null());
597 let q = unsafe { p.offset(1) };
598 assert!(!q.is_null());
599 assert!(q.is_not_null());
601 let mp: *mut int = mut_null();
602 assert!(mp.is_null());
603 assert!(!mp.is_not_null());
605 let mq = unsafe { mp.offset(1) };
606 assert!(!mq.is_null());
607 assert!(mq.is_not_null());
611 fn test_to_option() {
613 let p: *int = null();
614 assert_eq!(p.to_option(), None);
617 assert_eq!(q.to_option().unwrap(), &2);
619 let p: *mut int = mut_null();
620 assert_eq!(p.to_option(), None);
622 let q: *mut int = &mut 2;
623 assert_eq!(q.to_option().unwrap(), &2);
628 fn test_ptr_addition() {
630 let xs = box [5, ..16];
631 let mut ptr = xs.as_ptr();
632 let end = ptr.offset(16);
639 let mut xs_mut = xs.clone();
640 let mut m_ptr = xs_mut.as_mut_ptr();
641 let m_end = m_ptr.offset(16);
643 while m_ptr < m_end {
645 m_ptr = m_ptr.offset(1);
648 assert_eq!(xs_mut, box [10, ..16]);
653 fn test_ptr_subtraction() {
655 let xs = box [0,1,2,3,4,5,6,7,8,9];
657 let ptr = xs.as_ptr();
660 assert_eq!(*(ptr.offset(idx as int)), idx as int);
664 let mut xs_mut = xs.clone();
665 let m_start = xs_mut.as_mut_ptr();
666 let mut m_ptr = m_start.offset(9);
668 while m_ptr >= m_start {
670 m_ptr = m_ptr.offset(-1);
673 assert_eq!(xs_mut, box [0,2,4,6,8,10,12,14,16,18]);
678 fn test_ptr_array_each_with_len() {
680 let one = "oneOne".to_c_str();
681 let two = "twoTwo".to_c_str();
682 let three = "threeThree".to_c_str();
684 one.with_ref(|buf| buf),
685 two.with_ref(|buf| buf),
686 three.with_ref(|buf| buf),
693 let mut iteration_count = 0;
694 array_each_with_len(arr.as_ptr(), arr.len(), |e| {
695 let actual = str::raw::from_c_str(e);
696 let expected = expected_arr[ctr].with_ref(|buf| {
697 str::raw::from_c_str(buf)
700 "test_ptr_array_each_with_len e: {}, a: {}",
702 assert_eq!(actual, expected);
704 iteration_count += 1;
706 assert_eq!(iteration_count, 3u);
711 fn test_ptr_array_each() {
713 let one = "oneOne".to_c_str();
714 let two = "twoTwo".to_c_str();
715 let three = "threeThree".to_c_str();
717 one.with_ref(|buf| buf),
718 two.with_ref(|buf| buf),
719 three.with_ref(|buf| buf),
720 // fake a null terminator
727 let arr_ptr = arr.as_ptr();
729 let mut iteration_count = 0;
730 array_each(arr_ptr, |e| {
731 let actual = str::raw::from_c_str(e);
732 let expected = expected_arr[ctr].with_ref(|buf| {
733 str::raw::from_c_str(buf)
736 "test_ptr_array_each e: {}, a: {}",
738 assert_eq!(actual, expected);
740 iteration_count += 1;
742 assert_eq!(iteration_count, 3);
748 fn test_ptr_array_each_with_len_null_ptr() {
750 array_each_with_len(0 as **libc::c_char, 1, |e| {
751 str::raw::from_c_str(e);
757 fn test_ptr_array_each_null_ptr() {
759 array_each(0 as **libc::c_char, |e| {
760 str::raw::from_c_str(e);
766 fn test_set_memory() {
767 let mut xs = [0u8, ..20];
768 let ptr = xs.as_mut_ptr();
769 unsafe { set_memory(ptr, 5u8, xs.len()); }
770 assert!(xs == [5u8, ..20]);