The latter won’t allocate anything on its own, the [dynamic]int is just zeroed (nil pointer/0 length/0 capacity/no allocator). But as soon as some space is needed (e.g. from append, resize, or reserve), then it’ll allocate, after which it would need to be deleted to avoid leaking its memory.
make([dynamic]int), without a length or capacity, is actually similar. It sets the allocator that will be used when it allocates, but doesn’t immediately allocate anything.
If you want to see what’s happening internally, you can transmute it to runtime.Raw_Dynamic_Array:
darr: [dynamic]int
fmt.println(transmute(runtime.Raw_Dynamic_Array)darr)
// Raw_Dynamic_Array{data = 0x0, len = 0, cap = 0, allocator = Allocator{procedure = nil, data = 0x0}}
// data pointer is nil, so there's no allocation
append(&darr, 1, 2, 3)
fmt.println(transmute(runtime.Raw_Dynamic_Array)darr)
// Raw_Dynamic_Array{data = 0x17384018, len = 3, cap = 8, allocator = Allocator{procedure = proc(rawptr, Allocator_Mode, int, int, rawptr, int, Source_Code_Location) -> ([]u8, Allocator_Error) @ 0x43ECB0, data = 0x0}}
// data pointer has been set, the dynamic array has allocated
// the allocator has also been set to context.allocator since it wasn't specified
delete(darr)
fmt.println(transmute(runtime.Raw_Dynamic_Array)darr)
// Raw_Dynamic_Array{data = 0x17384018, len = 3, cap = 8, allocator = Allocator{procedure = proc(rawptr, Allocator_Mode, int, int, rawptr, int, Source_Code_Location) -> ([]u8, Allocator_Error) @ 0x43ECB0, data = 0x0}}
// note that the pointer is still set--it's no longer valid and shouldn't be used again without resetting the dynamic array (e.g. darr = {})
// of particular note, don't delete a dynamic array before you return it from a proc!