Structs

Structs define concrete structured types. Their values may live directly in stack storage, inline inside another value, or in explicitly allocated heap memory.

Declaration

A struct is declared at namespace level. Its fields have fixed types and are laid out in declaration order according to the selected target.

namespace Example;

struct Vector3
{
    public float X;
    public float Y;
    public float Z;
}

Member visibility is described separately in Access modifiers.

Fields may themselves contain other struct values. Recursive data structures use pointer fields so every value retains a finite, target-defined size.

Construction

Brace construction creates a value directly from accessible fields. Arguments follow field declaration order and no heap allocation occurs. A private field cannot be initialized this way from outside its declaring struct; use a public constructor or factory instead.

Vector3 position = Vector3 { 1.0f, 2.0f, 3.0f };

A struct may also declare constructors. Parenthesized construction invokes a matching constructor body.

struct Vector3
{
    public float X;
    public float Y;
    public float Z;

    public Vector3(float x, float y, float z)
    {
        X = x;
        Y = y;
        Z = z;
    }
}

Vector3 position = Vector3(1.0f, 2.0f, 3.0f);

Value semantics

Struct assignment, parameters and return values use value semantics. Assigning a struct produces an independent copy of its fields. Pointer fields are copied as pointer values and do not deep-copy the referenced memory.

Vector3 original = Vector3 { 1.0f, 2.0f, 3.0f };
Vector3 copy = original;

copy.X = 10.0f; // original.X is still 1.0f

Use . to access a field on a value:

float x = position.X;
position.Y = 8.0f;
Semantics are not storage

Value semantics describe how a struct is copied and passed. They do not restrict it to the stack: new T(...) places a struct in heap memory and returns T*.

Methods

Methods operate on an implicit instance. Fields may be referenced directly inside the method body.

struct Counter
{
    private int Value;

    public Counter(int initialValue)
    {
        Value = initialValue;
    }

    public void Add(int amount)
    {
        Value += amount;
    }

    public int Read()
    {
        return Value;
    }
}

Counter counter = Counter(10);
counter.Add(5);
int current = counter.Read();

Pointers and memory

Take the address of an existing value with &. Pointer member access uses -> to make the raw access explicit.

Vector3 value = Vector3 { 1.0f, 2.0f, 3.0f };
Vector3* pointer = &value;

pointer->X = 12.0f;
float y = pointer->Y;

new allocates a struct through Xenon's target-sized native allocator. Release it explicitly with free.

Vector3* heap = new Vector3(1.0f, 2.0f, 3.0f);

heap->Z = 9.0f;
free(heap);

If the struct declares a destructor, free invokes it before releasing the allocation.