Documentation channel: current development main at compiler checkpoint 1d7e15e. The latest tagged release is v0.0.3; pages identify APIs that are not yet released.

Memory

Strut has no tracing garbage collector. Safe ownership is deterministic: T* is the ordinary reference-counted owning pointer, and the object is destroyed when the final owning pointer is released.

Safe owning pointers

User* user := new(User { id: 1, name: "Ada" });
User* second := user;

Copying a safe pointer shares ownership. A null safe pointer traps on dereference rather than becoming native undefined behaviour.

Const pointees and const bindings

Strut keeps one canonical pointer spelling. const T* makes the pointer binding const; T* const makes the pointed-to value const; const T* const applies both.

const User* fixed_owner := user;
User* const read_only := user;
const User* const fixed_read_only := user;

Nested pointers and references

Pointer layers compose normally. T** is a safe pointer to a safe T*, and deeper pointer chains continue the same way. References to pointer bindings are supported with T*&. Pointers to references are deliberately rejected.

int* value := new(7);
int** pointer := new(value);
int*** triple := new(pointer);
int*& binding := ref(value);

print(***triple);

References

T& is non-owning, non-null, and non-rebindable. T& const prevents mutation through the reference. References avoid reference-count churn when ownership is not needed.

function print_user(User& const user) -> void {
    print(user.name);
}

Weak pointers

weak_ptr<User> weak := weak(user);
if (!weak.expired()) {
    User* locked := weak.lock();
}

Unsafe raw pointers

raw_ptr<T> is the unmanaged raw-pointer type. Convert a safe pointer with ptr(owner). Raw pointers exist for FFI and specialised low-level work and are restricted to explicit unsafe regions. Both *raw and familiar raw->member access are supported.

unsafe {
    raw_ptr<User> raw_user := ptr(user);
    print(raw_user->name);
}

Reference cycles

Reference counting cannot automatically collect strong cycles. Use weak_ptr<T> for back-references. The compiler warns for obvious cycles it can identify statically.