const expect = @import("std").testing.expect; const print = @import("std").debug.print; // Most programs need to keep track of buffers which don't have compile-time known lengths. // Many-item pointers are used for these. These act similarly to their single-item counterparts, // using the syntax `[*]T` instead of `*T`. // Here's a rundown of the differences between single and multi-item pointers. // Single-item pointers // * dereferenceable by `ptr.*` // * not indexable // * not supports arithmetic // * item size is any size, including unknown // * does not coerce from an array pointer // Multi-item pointers // * cannot be dereferenceable // * indexable by `ptr[0]` // * supports arithmetic // * item size is any size, including unknown // * coerces from an array pointer // Many-item pointers can have all of the same attributes, such as const, as single-item pointers. // In this example code, we've written a function that can take in a buffer of any length. // Notice how a single-item pointer to an array of bytes coerces into a many-item pointer of bytes. fn doubleAllManypointer(buffer: [*]u8, byte_count: usize) void { var i: usize = 0; while (i < byte_count) : (i += 1) buffer[i] *= 2; } test "many-item pointers" { var buffer: [100]u8 = [_]u8{1} ** 100; const buffer_ptr: *[100]u8 = &buffer; const buffer_many_ptr: [*]u8 = buffer_ptr; doubleAllManypointer(buffer_many_ptr, buffer.len); for (buffer) |byte| try expect(byte == 2); const first_elem_ptr: *u8 = &buffer_many_ptr[0]; const first_elem_ptr_2: *u8 = @ptrCast(buffer_many_ptr); try expect(first_elem_ptr == first_elem_ptr_2); } // Think about what might happen if you passed that function the incorrect `byte_count`. // The programmer is expected to keep track of (or otherwise know) the length of these buffers. // It's worth noting that this function is effectively trusting us to pass us a valid length for the given buffer. // We can convert from a many-item pointer to a single-item pointer by either indexing an element and dereferencing that, // or by using `@ptrCast` to cast the pointer type. This is only valid when the buffer has a length of at least 1.