Pointers in Nim
import std/strformat
# We'll show how pointers work in contrast to values with
# 2 procedures: `zeroval` and `zeroptr`. `zeroval` has an
# `int` parameter, so arguments will be passed to it by
# value. `zeroval` will get a copy of `ival` distinct
# from the one in the calling procedure.
proc zeroval(ival: int) =
var ival = ival # Create a mutable copy
ival = 0
# `zeroptr` in contrast has a `ptr int` parameter, meaning
# that it takes an `int` pointer. The `iptr[]` syntax in the
# procedure body then dereferences the pointer.
# Assigning a value to a dereferenced pointer changes the
# value at the referenced address.
proc zeroptr(iptr: ptr int) =
iptr[] = 0
proc main() =
var i = 1
echo fmt"initial: {i}"
zeroval(i)
echo fmt"zeroval: {i}"
# The `addr` function gives the memory address of `i`,
# i.e. a pointer to `i`.
zeroptr(addr i)
echo fmt"zeroptr: {i}"
# Pointers can be printed too.
echo fmt"pointer: {cast[int](addr i)}"
main()
Nim supports pointers, allowing you to pass references to values and records within your program.
In this example, we demonstrate how pointers work in contrast to values using two procedures: zeroval
and zeroptr
.
The zeroval
procedure takes an int
parameter, so arguments are passed to it by value. This means zeroval
receives a copy of the value, distinct from the one in the calling procedure.
The zeroptr
procedure, on the other hand, takes a ptr int
parameter, which is a pointer to an int
. Inside the procedure, we use the iptr[]
syntax to dereference the pointer and access or modify the value it points to.
In the main
procedure, we create a variable i
and demonstrate the difference between passing by value and passing by reference:
- We pass
i
tozeroval
, which doesn’t change the originali
. - We pass
addr i
(the address ofi
) tozeroptr
, which does change the originali
because it has a reference to the memory address of that variable.
Finally, we print the pointer itself, which is the memory address of i
. In Nim, we need to cast the pointer to an integer to print its raw value.
To run this program, save it as pointers.nim
and use the Nim compiler:
$ nim c -r pointers.nim
initial: 1
zeroval: 1
zeroptr: 0
pointer: 140732920764540
Note that zeroval
doesn’t change the i
in main
, but zeroptr
does because it has a reference to the memory address for that variable.