const std = @import("std");
const expect = std.testing.expect;
const bytesAsSlice = std.mem.bytesAsSlice;
test "address of syntax" {
// Get the address of a variable:
const x: i32 = 1234;
const x_ptr = &x;
// Dereference a pointer:
expect(x_ptr.* == 1234);
// When you get the address of a const variable,
// you get a const pointer to a single item.
expect(@TypeOf(x_ptr) == *const i32);
// If you want to mutate the value,
// you'd need an address of a mutable variable:
var y: i32 = 5678;
const y_ptr = &y;
expect(@TypeOf(y_ptr) == *i32);
y_ptr.* += 1;
expect(y_ptr.* == 5679);
}
test "pointer array access" {
// Taking an address of an individual element gives a
// pointer to a single item. This kind of pointer
// does not support pointer arithmetic.
var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const ptr = &array[2];
expect(@TypeOf(ptr) == *u8);
expect(array[2] == 3);
ptr.* += 1;
expect(array[2] == 4);
}
test "pointer slicing" {
var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
const slice = array[2..4];
expect(slice.len == 2);
expect(array[3] == 4);
slice[1] += 1;
expect(array[3] == 5);
}
test "comptime pointers" {
comptime {
var x: i32 = 1;
const ptr = &x;
ptr.* += 1;
x += 1;
expect(ptr.* == 3);
}
}
test "@ptrToInt and @intToPtr" {
const ptr = @intToPtr(*i32, 0xdeadbee0);
const addr = @ptrToInt(ptr);
expect(@TypeOf(addr) == usize);
expect(addr == 0xdeadbee0);
}
test "comptime @intToPtr" {
comptime {
const ptr = @intToPtr(*i32, 0xdeadbee0);
const addr = @ptrToInt(ptr);
expect(@TypeOf(addr) == usize);
expect(addr == 0xdeadbee0);
}
}
test "volatile" {
const mmio_ptr = @intToPtr(*volatile u8, 0x12345678);
expect(@TypeOf(mmio_ptr) == *volatile u8);
}
test "pointer casting" {
const bytes align(@alignOf(u32)) = [_]u8{ 0x12 } ** 4;
const u32_ptr = @ptrCast(*const u32, &bytes);
expect(u32_ptr.* == 0x12121212);
// Even this example is contrived,
// there are better ways to do the above than pointer casting.
// For example, using a slice narrowing cast:
const u32_value = bytesAsSlice(u32, bytes[0..])[0];
expect(u32_value == 0x12121212);
// And even another way, the most straightforward way to do it:
expect(@bitCast(u32, bytes) == 0x12121212);
}