Although pointers offer a similar capability to references, they are handled quite differently. Pointers offer more power and versatility than references, but do so without the security of compiler-enforced safety.
- Pointers are declared using * (rather than & for references).
- Pointers are never automatically dereferenced. The * operator must be explicitly used to view or change the object it points to.
- Pointers may only be used within a trust block.
- Like borrowed references, pointers never belong to an allocator nor are managed by one.
- Using pointers safely is solely the responsibility of the programmer. No memory safety enforcement mechanisms, such as lifetime constraints, apply to pointers.
A pointer is typically created by copying (coercing) a reference. Such pointer creation need not happen within a trust block:
imm nbr = 3 imm nbrptr *mut i32 = &nbr // Create a pointer from a reference trust *nbrptr = 4 // trust block required to use the pointer
The reverse is also possible, going from a pointer back to a reference.
trust val.nbrref = nbrptr
However, this must be done within a trust block because the usual safety checks are not performed. The only type checks performed are for matching value type and permissions. No attempt is made to verify that the pointer (or reference) points to a valid object nor that it is managed by the reference's allocator.
Another way to create a pointer is to call an FFI function that returns a pointer.
Pointers support addition and subtraction with unsigned integers. The integer dispacement is automatically multipled by the byte size of the object pointed to.
trust imm nbrptr *mut i32 = &nbr nbrptr += 1; // Adds 4 to the pointer's address, the byte-size of i32
Notice how this last example works differently when applied to a reference. Using the += on a reference applies that method's operation to the object it refers to, as opposed to changing the reference itself.
Additionally, two pointers may be subtracted from each other or compared.