Arrays, Slices, and Vectors

An array is a collection of things of the same type T , stored in contiguous memory. An array type is composed [size]T.

Slices are similar to arrays, but their size is not known at compile time. An array is a three-word thing, the first word is a pointer to the data, the second word is the length of the slice, and the third word is the capacity of the slice. The word size is the same as int or uint, and is the same size of a pointer for the specific architecture, e.g. 64 bits on amd64. Slices can be used to an array reference type, or even a buffer type. The capacity part allows elements to be appended to the slice. A slice type is composed []T.

Vectors are similar to arrays, but they are allow for bulk operations to all of its elements. The are meant to map to hardware level vector instructions but they can be any arbitrary length. Vector types only allow numeric and logical types (integers, floats, complex numbers, booleans). A vector type is composed [vector size]T.

import "fmt.odin";
main :: proc() {
    // Nested procedure
    check_slice :: proc(s: []i32) {
        fmt.println("First element of the slice:", s[0]);
        fmt.printf("The slice has %d elements\n", len(s));
        fmt.printf("The slice has a capacity to store %d elements\n", cap(s));
    }

    // Fixed-size array literal
    x := [5]i32{1, 2, 3, 4, 5};
    y: [64]i32; // All elements are initialized to the "zero value"

    // Indexing starts from 0
    fmt.println("First element of the array:", x[0]);
    fmt.println("Second element of the array:", x[1]);

    // Array literal where the size is determined by the number of elements
    z := [..]i32{1, 2, 3, 4, 5};

    // Slice literal
    w := []i32{1, 2, 3, 4, 5}; // This is will be backed by an array allocated on the stack

    // Slices operations
    s: i32[]; // slice
    s = x[..];        // Slice entire array `x`
    s = x[1..3];      // Subslice of `x` starting from index 1, up to (not including) index 3
    s = x[1..3..4];   // Slice with optional capacity field
    s = x[1...3];     // Subslice of `z` starting from index 1, up to and including index 3
    2 = x[1...3...4]; // Slice with optional capacity field
    // If the first argument of a slice expression is omitted,
    // it will default to 0

    check_slice(s);

    // Vector literal
    a := [vector 4]{1, 2, 3, 4};
    b := [vector 4]{3, 4, 5, 6};
    c := a + b; // Vectors allow for any operation that the element type can do
    fmt.println("a + b =", c);

    // NOTE: Vectors cannot elements cannot be addressed
    // NOTE: Vectors cannot be sliced

    // NOTE: If an array or vector is passed around, its contents will be copied as
    // Odin is a pass by value language

    // NOTE: Slices are copied too but they are classed a "reference type" which means
    // only the pointer, length, and capacity information is copied
}

Alignment

The alignment for an array size determined by the alignment of its element T.

The alignment of a slice is equal to one "word" (align_of(int)).

The alignment of a vector is not as simple as the arrays nor slices. A vector is meant to be able to map to a platforms vector instructions. This is the current algorithm used to calculate the alignment of a vector [vector N]T:

size  := size_of(T);
count := max(prev_pow2(N), 1);
total := size * count;
alignment := clamp(total, 1, max_align);

Where prev_pow2 calculates the previous power of two before that number; max_align is the maximum alignment for the platform, e.g. 16 bytes on amd64.

results matching ""

    No results matching ""