PVG
43. Removing Implicit Allocations — Program Video Games

43. Removing Implicit Allocations

The text version of this lecture will be different. Rather than going through every change, I will explain the Odin language change and what it means going forward.

As of the 2025 version of Odin, implicit allocations are being phased out.

An example of an implicit allocation is:

my_array := [dynamic]int{1, 2, 3}

Because this array is dynamic, it's memory is allocated using `context.allocator.

A more common example in our code:

My_Type :: struct {
    some_values: [dynamic]int
}

my_instance := My_Type {
    some_values = {1, 2, 3} // Looks static here, but is dynamically allocated
}

The issue extends to the map type as well, which we use in our code.

To get around this issue, we essentially create the dynamic containers and then add data to them.

my_array: [dynamic]int // created
append(&my_array, ..[]int{1, 2, 3}) // append a static slice to the array
// or
append(&my_array, 1)
append(&my_array, 2)
append(&my_array, 3)

Now it's clear to the programmer that memory is being allocated.

For map:

My_Type :: struct {
    table: map[string]int
}

// Instead of:

my_instance := My_Type {
    table = {
        "apples" = 3,
        "oranges" = 4,
    }
}

// Do this

my_instance: My_Type
my_instance.table["apples"] = 3
my_instance.table["oranges"] = 4

If there are nested dynamic types, such as a dynamic array in a map:

My_Type :: struct {
    table: map[string][dynamic]int
}

my_instance: My_Type
my_instance.table["apples"] = {} // Instantiate the dynamic array
append(&my_instance.table["apples"], 3) // Now we can append

If you want to avoid this change entirely, you can declare: #+feature dynamic-literals at the top of the offending file to turn the feature on.