Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing a struct as a pointer or not

Tags:

go

type Vertex struct {
    X, Y float64
}

func main() {
    v := Vertex{3, 4}
    fmt.Println(v)

    d := &Vertex{3, 4}
    fmt.Println(d)
}

http://play.golang.org/p/XluyUHL2y7

What's the difference between these two ways to initialize a Vertex struct?

I know that second one is allocation with pointer, but I can't see any difference of this solution in practice.

like image 959
Kir Avatar asked Oct 16 '13 21:10

Kir


1 Answers

TL;DR There is no difference1. Whether a variable is allocated on the stack or heap depends on its usage.

I did a deep dive on the the assembly Go generates from various initialization and calling cases. The assembly generated between v and b is nearly the same. Of particular note, d is not allocated on the stack1.

What determines whether a variable is heap allocated or stack allocated is how it is used. Passing a passing a pointer into a function that only used the parameter as a value will not force a variable to be heap allocated. But even this isn't guaranteed, the spec allows any Go compiler to freely move variables between the stack an heap as needed for optimization or code generation. Go abstracts away Heap vs Stack just as C/C++ abstracts away RAM vs Register.

http://play.golang.org/p/vJQvWPTGeR

type Vertex struct {
    X, Y float64
}

func PrintPointer(v *Vertex) {
    fmt.Println(v)
}

func PrintValue(v *Vertex) {
    fmt.Println(*v)
}

func main() {
    a := Vertex{3, 4} // not allocated
    PrintValue(&a)

    b := &Vertex{3, 4} // not allocated
    PrintValue(b)

    c := Vertex{3, 4} // allocated
    PrintPointer(&c)

    d := &Vertex{3, 4} // allocated
    PrintPointer(d)
}

1: technically not true, but would be true if fmt.Println(*d) had been used instead. I cheated a little to answer the question I think you meant to ask.

like image 77
deft_code Avatar answered Oct 11 '22 20:10

deft_code