Structures

// Named structure with no fields
Empty :: struct{};

// Named structure with three fields
Vector3 :: struct {
    x: f32;
    y: f32;
    z: f32;
}

// Structures can be used as fields of other structures
Box :: struct {
    position, dimension: Vector3;
}

x: struct{x, y: f32}; // Variable with anonymous structure with two fields

main :: proc() {
    // Declare a `Vector3`
    point := Vector3{1.2, -0.3, 7.4};
    // Assign particular fields in a structure literal
    another_point := Vector3{z = 1, x = 2, y = 3};

    rect := Box {
        position  = Vector3{1, 4, 9},
        dimension = Vector3{1, 2, 4},
    };

    // Accessing a struct member
    fmt.println(rect.position.x);

    // Assigning a value
    rect.position.x = 123;
}

Memory layout

A structure's memory layout by default is arranged to minimize alignment padding (and thus its size).

A :: struct{x: u32; y: u8};
B :: struct{y: u8; x: u32};
compile_assert(size_of(A) == size_of(B));

This differs from how most languages construct structures. To have the members of a structure be is the same order as in memory (C-like), the #ordered tag can be used.

A :: struct #ordered {
    a: u32;
    b: u8;
    c: f32;
}

To remove all extra memory padding, the #packed tag can be used.

A :: struct #packed {
    a: u32;
    b: u8;
    c: u16;
    d: u8;
}
compile_assert(size_of(A) == 8);

#ordered and #packed can not be used to together.

To force a specific alignment to a structure, the #align tag can be used. The alignment specified must be a power of 2 and in bytes.

A :: struct #align 8 {
    a: u8;
}

The#raw_union tag will cause each field to share the same memory offset, zero, and the size of the largest field. This is equivalent to C's union. Accessing fields is unsafe if the data is not expected.

Data :: struct #raw_union {
    f: f64;
    i: i64;
    s: string;
    b: bool;
    c: complex128;
};

d: Data;
d.f = 123;
d.s = "jellied eels";

These are very useful when interfacing with C-library that require C-like unions. They are also useful mathematical objects:

Vector3 :: struct #raw_union {
    using xyz: struct {x, y, z: f32};
    e: [3]f32;
};

Accessing fields

Structure fields are accessed by using a dot.

Vector2 :: struct{x, y: f32};
main :: proc() {
    v := Vector2{4, 9};
    v.x = 2;
    fmt.println(v);
}

Structure fields can accessed through a pointer. To access the x field of a pointer to the structure, p^.x could be written however, Odin allows us to write just p.x, without the explicit deference. This is to help with refactoring when changing variables from pointer to values, and vice versa.

v := Vector2{4, 9};
p := &v;
p.x = 1.23;
fmt.println(v);

results matching ""

    No results matching ""