Skip to content

proposal: spec: allow conversion from *T to *[1]T (and therefore []T) #76135

@jakebailey

Description

@jakebailey

Proposal Details

In short, allow this code:

x := 1234
ptr := &x

arr := (*[1]int)(ptr) // <-- new
slice := arr[:]       // <-- already legal today

We already have the ability to "convert" slices to pointers by way of taking the address of their elements. But, if you already have a pointer and want to give it to something that wants an array (or slice), you need to allocate new memory and copy the data in, which is less optimal.

But, a pointer to T is the same as having a single element array of that thing; it's not unsafe to use that same pointer, but today requires unsafe or similar.

Conversions from *[1]T to []T are already legal, so this would pair nicely, though unfortunately there's a nil check emitted for that case (rather than just creating a nil slice).

See also #76109


  • Would you consider yourself a novice, intermediate, or experienced Go programmer?
    • Experienced
  • What other languages do you have experience with?
    • TypeScript, C, Python
  • Would this change make Go easier or harder to learn, and why?
    • Probably no difference? This is something you can do directly in C, or via unsafe in Go today.
  • Has this idea, or one like it, been proposed before?
    • proposal: slices: add FromPointer function #76109, more or less; it's a library func that would do the same thing, but a nil check.
    • This follows on from the existing ability to convert between slices and arrays, which was added in Go 1.17 and expanded in Go 1.20.
      • A quick search did not net me the links to these proposals (I will keep searching).
  • Who does this proposal help, and why?
    • Those trying to write more optimial code with slices/arrays; an address can be used as a single-element array without allocation, in the same way as &[1]int{x}[0] is allowed in the opposite direction.
  • What is the proposed change?
    • Please describe as precisely as possible the change to the language.
      • Allow conversion from pointer to T to pointer to array of 1 T.
    • What would change in the language spec?
      • In a new section similar to the existing "Conversions from slice to array or array pointer" section of the spec, add a new conversion rule:
        • "Pointer to T to pointer to array of 1 T: A pointer to a type T can be converted to a pointer to an array of 1 T. The result points to an array whose single element is the value pointed to by the original pointer."
    • Please also describe the change informally, as in a class teaching Go.
      • This change would allow you to treat a pointer to a single value as a pointer to an array of one element, which have identical memory layouts.
  • Is this change backward compatible?
    • Yes.
  • Show example code before and after the change.
    • Before:
      var x int
      arr := (*[1]int)(unsafe.Pointer(&x))
      slice := (*[1]int)(unsafe.Pointer(&x))[:]
    • After:
      arr := (*[1]int)(&x)
      slice := (*[1]int)(&x)[:]
  • What is the cost of this proposal? (Every language change has a cost).
    • How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?
      • Those using typechecks would need to be updated.
    • What is the compile time cost?
      • Minimal.
    • What is the run time cost?
      • None.
  • Can you describe a possible implementation?
    • This is largely a compiler change; my memory might not be recalling correctly, but that implies allowing the conversion in the type checker, likely no changes in walk, then an SSA rule to implement this conversion op?
  • How would the language spec change?
    • See above (duplicate bullet in the lang change template)
  • Orthogonality: how does this change interact or overlap with existing features?
    • This feature pairs well with existing improvements to slices/array conversions, which expanded in Go 1.17 and Go 1.20.
  • Is the goal of this change a performance improvement?
    • Yes, though this is a pretty low-level optimization. Its closest ana
  • Does this affect error handling?
    • No.
  • Is this about generics?
    • No.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions