Composite literals oddity with methods

I wonder, why composite literals are treated differently than structs, when it comes to methods.
As can be seen in the Playground Example, Go deals with an actual argument of a method call automatically:

  • a pointer is de-referenced in case of value receiver
  • a value’s address is calculated in case of a pointer receiver

With composite literals, its different:

  • a pointer is de-referenced in case of value receiver (ok)
  • a composite literal’s address is NOT automatically calculated in case of a pointer receiver (why not?)

When I explicitly take the composite literal’s address, it works.

Please help - I would really like to understand this.
(Please note, that I’m not considering interfaces here, where things are quite different)

Playground Code is here

BR volker

Only addressable objects can be automatically “converted” to expressions that take their address, however, there’s a special case for composite literals:

As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.

In the Composite literals section of the spec, it says:

Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal’s value.

var pointer *Point3D = &Point3D{y: 1000}

Maybe this means that in order to satisfy the language’s addressability requirement for pointer method receivers, a hidden variable is created (at least conceptually*) and the methods are called from that variable. I’m not a language expert, so you might need to find some official Go forum/mailing list/etc. to get more info from someone on the Go team, or perhaps someone else on this forum knows more.

* I mean here that it might just be a rule of the language and perhaps not of the compiler. For all I know, the compiler might generate code that allocates the literal to the heap and keeps the address in a register, never allocating a space for the pointer itself on the stack/heap, and then via the internal ABI, calls the pointer receiver method with the value in the register.

1 Like