1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
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);
}
|