2.10.1 Pointers and Addresses

The Linux operating system uses a technique called
virtual memory to provide each user process
with its own virtual view of the memory resources on your
system. A virtual view of memory resources is referred to as an
address space. An address space associates
a range of address values, either [0 ...
0xffffffff] for a 32-bit address space or [0
... 0xffffffffffffffff] for a 64-bit address space,
with a set of translations that the operating system and
hardware use to convert each virtual address to a corresponding
physical memory location. Pointers in D are data objects that
store an integer virtual address value and associate it with a D
type that describes the format of the data stored at the
corresponding memory location.

You can explicitly declare a D variable to be of pointer type by
first specifying the type of the referenced data and then
appending an asterisk (*) to the type name.
Doing so indicates you want to declare a pointer type, as shown
in the following statement:

int *p;

This statement declares a D global variable named
p that is a pointer to an integer. The
declaration means that p is a 64-bit integer
with a value that is the address of another integer located
somewhere in memory. Because the compiled form of your D code is
executed at probe firing time inside the operating system kernel
itself, D pointers are typically pointers associated with the
kernel's address space. You can use the arch
command to determine the number of bits that are used for
pointers by the active operating system kernel.

If you want to create a pointer to a data object inside of the
kernel, you can compute its address by using the
& operator. For example, the operating
system kernel source code declares an unsigned long
max_pfn variable. You could trace the address of this
variable by tracing the result of applying the
& operator to the name of that object in
D:

trace(&`max_pfn);

The * operator can be used to refer to the
object addressed by the pointer, and acts as the inverse of the
& operator. For example, the following
two D code fragments are equivalent in meaning:

q = &`max_pfn; trace(*q);
trace(`max_pfn);

In this example, the first fragment creates a D global variable
pointer q. Because the
max_pfn object is of type unsigned
long, the type of &`max_pfn is
unsigned long * (that is, pointer to
unsigned long), implicitly setting the type
of q. Tracing the value of
*qfollows the pointer back to the data object
max_pfn. This fragment is therefore the same
as the second fragment, which directly traces the value of the
data object by using its name.