Go

What does this program print? (append inside a function with spare capacity)

Question 41HardGo 1.22 to 1.25
func add(s []int) {
	s = append(s, 4)
	s[0] = 100
}

func main() {
	s := make([]int, 3, 4)
	add(s)
	fmt.Println(s, len(s), cap(s))
	fmt.Println(s[:4])

	t := []int{1, 2, 3} // len 3, cap 3
	add(t)
	fmt.Println(t)
}

Output:

[100 0 0] 3 4
[100 0 0 4]
[1 2 3]

In the first call cap is 4, so append writes 4 into the shared backing array at index 3 and makes no new allocation. s[0] = 100 also hits the shared array. The caller's header still says len 3, so it prints three elements. Reslicing to s[:4] (allowed up to cap) shows the hidden 4.

In the second call cap == len, so append allocates a new array, copies into it, and points the local s at it. s[0] = 100 then changes the new array, and the caller's t stays the same.

Key insight: whether a mutation "leaks" back to the caller depends on spare capacity at run time. That makes these bugs data-dependent and hard to reproduce.

More on Arrays, Slices, Maps & Strings

All 37 Arrays, Slices, Maps & Strings questions