Go: proposal: Go 2: integer array <-> integer type conversion

Created on 4 Mar 2020  ·  11Comments  ·  Source: golang/go

Integer types are convertable to each other. I propose to extend it to arrays:

a := [2]uint16{1, 2}
b := int32(a)
c := [4]byte(a)

d := uint32(65537)
e := [2]int16(d)

This will allow to see:

  • sub-bytes or sub-words of a larger integer variable
  • bytes/words in an array as a larger integer

without unsafe.Pointer tricks.

Go2 LanguageChange Proposal

Most helpful comment

We aren't going to intentionally make simple programs (that don't use unsafe) generate different results on different systems.

If we adopt little endian conversions as suggested above, what is the advantage of allowing these conversions? It's always possible to write these conversions out directly. Does this really come up often enough to add a somewhat obscure conversion?

All 11 comments

What should the endianness of the converted value be?

For language change proposals, please fill out the template at https://go.googlesource.com/proposal/+/refs/heads/master/go2-language-changes.md .

When you are done, please reply to the issue with @gopherbot please remove label WaitingForInfo.

Thanks!

This can be done now using encoding/binary. The compiler generates very good code for these routines, equivalent (I strongly suspect) to what a built-in conversion would do. It would be good to explain why encoding/binary is insufficient here.

  • I am experienced Go programmer.
  • I have extensive experience with C, C++, Python.
  • This change enhances type conversions and eliminates some uses of unsafe.Pointer (a more advanced feature) or shift & convert, so I believe this change slightly extends what novice programmers can do and it can improve Go learning experience.
  • Afaik this feature was not proposed before.
  • All Go users benefit from this with extended type conversions.
  • This proposal introduces a) integer array <-> integer array b) integer array <-> integer type conversions.
  • The language spec would extend with the proposed conversions.
  • This change is backward compatible.
  • I believe implementation cost is minimal.
  • Compile time cost is similar to integer <-> integer conversion.
  • There is no run time cost.
  • Like a uint64(int64) conversion, this change is a unique feature and orthogonal with other features in Go.
  • This change is not a performance improvement, just a convenient type conversion.

@gopherbot please remove label WaitingForInfo

What should the endianness of the converted value be?

Whatever the target's endianness is at compile time. It should behave like an unsafe.Pointer conversion.

Whatever the target's endianness is at compile time.

This was discussed indirectly at https://github.com/golang/go/issues/35398

Ok, so because of endianness:

a := uint16(258)
b := [2]byte(a)

c := byte(a) // always 2
d := b[0]    // not well defined

right? We cant just think like unsafe.Pointer conversion.

How about we make it well-defined. We define the conversion such that b[0]=c=2 and b[1]=1 is always true and consistent across platforms. What do you think?

Josh, encoding/binary doesn't seem very convenient in terms of intuition & readability. It looks more suitable for run-time conversion, whereas this is a compile time feature. Though I am sure the compiler can be made to output efficient assembly for it.

It looks more suitable for run-time conversion, whereas this is a compile time feature.

I’m not sure I understand the distinction here. I believe that are functionally identical. Can you explain more?

sorry yes, runtime/compile time distinction is not accurate since we need byte swap operations on some platforms to get the consistency.

We aren't going to intentionally make simple programs (that don't use unsafe) generate different results on different systems.

If we adopt little endian conversions as suggested above, what is the advantage of allowing these conversions? It's always possible to write these conversions out directly. Does this really come up often enough to add a somewhat obscure conversion?

I guess you are right in that:

  • we can live without it
  • shift & convert is pretty common for sub-byte access
  • little-endianizing a variable is too specific a choice (why not big?)
Was this page helpful?
0 / 5 - 0 ratings