Types you define · 3 MIN READ

Returning a pointer to a local is fine

Explain why Go lets you return the address of a local variable.

In C this is the classic mistake: return the address of a local and the stack frame is gone by the time the caller looks. Go removes the mistake rather than warning about it. The compiler works out that the value outlives the function — escape analysis — and allocates it somewhere that survives.

So return &Config{} is ordinary, idiomatic Go, and constructors called New... do it constantly. You are not choosing stack or heap; the compiler is, from how the value is used.

What this does not mean is that pointers are free. An escaping value becomes garbage collector work, which is the real cost behind "pointers are faster" being a guess rather than a rule.

SEE THE IDEA

The value outlives the returning function

  1. 01

    Create

    go
    item := Item{}

    The function creates a local value

  2. 02

    Return reference

    go
    return &item

    The caller may retain it

  3. 03

    Use safely

    go
    p.Name = "go"

    The value remains valid

Go keeps reachable values alive; a returned pointer is not a dangling reference.

In practice

Escape analysis decides where storage can live while preserving language semantics. Returning a pointer to a local is safe, but it may require heap storage. Prefer the API shape that expresses ownership and optionality clearly, then inspect allocation behavior if a measured hot path needs improvement.

Watch out

Safe lifetime does not mean synchronized access. Sharing the returned pointer across goroutines still requires coordination.

Official reference ↗

Read and predict

go
package main

import "fmt"

type Config struct {
	Name string
}

func New(name string) *Config {
	local := Config{Name: name}
	return &local
}

func main() {
	first := New("a")
	second := New("b")
	fmt.Println(first.Name, second.Name, first == second)
}

Does this compile, and what does it print?

Try it yourself

Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.

Progress stays in this browser. No account needed.