Created on 2024-03-12; last updated on 2024-05-13
A pointer is a memory address allowing us to read and possibly write data at that address.
Every pointer has a pointer type.
Zig makes a distinction between four types of pointer type:
In addition, optional, function and type-erased pointers deserve mention.
Every pointer type has the following attributes:
- size, which determines the pointer type;
- child type, which tells us how to interpret the data to which the pointer points;
- alignment;
- address space;
const;volatile;allowzero, and- sentinel value (for many-item pointers and slices only).
The size of each pointer type is machine-dependent. Single-item, many-item and C pointer types have a size equal to the size of the usize integral type. Slice types, representing fat pointers, have a size equal to twice the size of usize.
Pointers can be used at compile time as long as their child type has a well-defined memory layout.
We use the @ptrCast builtin function to reinterpret pointers as having a different pointer type. @ptrCast changes a pointer's child type while also performing any additional necessary casts that would have taken place implicitly, such as:
- casting an optional pointer to a nonoptional pointer (with safety checking);
- decreasing pointer alignment, and
- discarding the sentinel value in a single-item pointer to a sentinel-terminated array, a sentinel-terminated many-item pointer or sentinel-terminated slice.
We can also use @ptrCast to restructure (slices of) compile time-only arrays. This functionality allows us to, e.g., index a one-dimensional array as if it were an equally sized multidimensional array.
We can't supply an undefined pointer to @ptrCast.
Currently, @ptrCast allows the casting of double pointers to single pointers but there is an accepted proposal to prohibit this.
Interconversion between integers and pointers is possible with the @ptrFromInt and @intFromPtr builtin functions. Conversions involving the zero memory address are checked for illegal behavior. Conversions of integer addresses to pointers are checked for proper alignment.
There is an accepted proposal to check for illegal behavior when using @ptrCast and @intToPtr. If implemented, this proposal would make it a compile-time error to call @ptrCast or @intToPtr when the pointed-to memory is undefined or the in-memory layout of the source child type does not match the layout of the destination child type.
There is an accepted proposal to add support for pointer subtraction.
Undefined pointers can represent any value, even the zero memory address. What does it mean for a pointer that is not optional to be undefined? This has been identified as a design flaw.