A pointer is an address data type. It is used to store the address of another variable. In Jai, just like C, pointers are defined using the * marker; but beware, the syntax is a bit different from C or C++.

a : int = 42; // Just a normal integer
b : *int;     // Here's a pointer to a integer.

b = *a; // Point b at a.
print("Value of a is %, address of a is %\n", a, *a);
print("Value of b is %, but b points at address %\n", <<b, b);
Example output
Value of a is 42, address of a is 7fff_9ca3_1e28
Value of b is 42, but b points at address 7fff_9ca3_1e28

As you can see there, we use unary * to get the address of a variable, and unary << to dereference a pointer.

Pointer Arithmetic

A pointer is a data address, which is a numeric value. You can perform arithmetic operations such as +, -, *, and / on a pointer just as you can on a numeric value. You can check pointers for equality using ==, !=, <, <=, >, and >=.

array: [10] int
a: *int = array.data; // set a to point to array.data
a += 1;

In the example above, incrementing pointer a by 1 adds 8 to the pointer, since a 64-bit integer consists of 8 bytes. A pointer increments depending on the size of the data the pointer points to.

void pointer

variable: *void; is a void pointer, or a pointer with no associated data type. A void pointer can hold the address of any type and can be typcasted to any type. void pointer has the same functionality as in C.

Pointers to Pointers

Just like in C++, pointers can also point to other pointers, allowing multiple indirection.

a: int = 3;
b: *int = *a;
c: **int = *b;
d: ***int = *c;
print("%\n", << << << d); // prints out the value of a, which is 3

Function Pointers

Function pointers can be declared almost in the same way as regular functions.

function :: (a: int, b: int)->int { // declare function
  return a + b; 

f_ptr: (int,int)->int = function;

// call the function that the function pointer is pointing to
c := f_ptr(1,2); 

Relative pointers

Relative pointers are a way of having a pointer that is not a 64-bit pointer. Instead, the pointer can be 32-bit, 16-bit, or 8-bit. These pointers are serializable.

Obj :: struct { var:= 0; }

ptr: *~s32 Obj; // 32-bit relative pointer to an Obj
ptr: *~s16 Obj; // 16-bit relative pointer to an Obj
ptr: *~s8  Obj; //  8-bit relative pointer to an Obj

Relative pointers use the same syntax and operators as normal pointers for assigning and derefering pointers.