That code doesn't even compile in go 1.22 or go.1.21:
https://go.dev/play/p/mPCBUQizSVo
./prog.go:20:14: cannot convert unsafe.Pointer(s) (value of type 
unsafe.Pointer) to type []To

What's the underlying requirement? In the test case it looks like you want 
to take a slice of int32's, in whatever their internal in-memory 
representation is, and re-represent them as a slice of half as many 
int64's?? Then of *course* each pair of int32's will become one int64, and 
the order of the hi/lo halves will depend entirely on the system's internal 
representation of int64's. It *is* working, in the sense that it's doing 
exactly what you told it to do. There's a reason why the "unsafe" package 
is called "unsafe"!

It would be straightforward to write a function which takes a slice 
containing pairs of int32's and assembles them into int64's in a consistent 
way. What you've not explained is:
- why you need to do this with generics (for example, what behaviour would 
you expect from other types?)
- why you need to do this in-place with "unsafe"

On Wednesday 8 May 2024 at 10:24:30 UTC+1 Srinivas Pokala wrote:

> Hello gopher's,
>
> I have simple go program which convert slice of one type to slice of other 
> type using go generics for handling all the supported types.
> Below is the code snippest for this:
> package main
>
> import "fmt"
> import "unsafe"
>
> type slice struct {
>         ptr unsafe.Pointer
>         len int 
>         cap int 
> }
>
> func Slice[To, From any](data []From) []To {
>         var zf From
>         var zt To
>         var s = (*slice)(unsafe.Pointer(&data))
>         s.len = int((uintptr(s.len) * unsafe.Sizeof(zf)) / 
> unsafe.Sizeof(zt))
>         s.cap = int((uintptr(s.cap) * unsafe.Sizeof(zf)) / 
> unsafe.Sizeof(zt))
>         x := ([]To)(unsafe.Pointer(s))
>         return x
> }
> func main() {
>         a := make([]uint32, 4, 13) 
>         a[0] = 1 
>         a[1] = 0 
>         a[2] = 2 
>         a[3] = 0 
>         // 1 0 2 0
>         b := Slice[int64](a)
>         //Expecxted : []int64[]{0x00000000 00000001,  0x00000000 00000002}
>         //Got: []int64{0x00000001 00000000, 0x00000002 0000000}
>         if b[0] != 1 { 
>                 fmt.Printf("wrong value at index 0: want=1 got=0x%x \n", 
> b[0])
>         }
>         if b[1] != 2 { 
>                 fmt.Printf("wrong value at index 1: want=2 got=0x%x\n", 
> b[0])
>         }
>
> }
>
> This is working fine on little endian architectures(amd64,arm64 etc), but 
> when i run on big endian machine(s390x) it is not working , it is resulting 
> wrong data
> //Expecxted : []int64[]{0x00000000 00000001,  0x00000000 00000002}
>  //Got: []int64{0x00000001 00000000, 0x00000002 0000000}
> Can somepoint point me how do we write such scenario which should work on 
> both little/endian platforms.
> Any leads on this?
>
> Thanks,
> Srinivas
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/a5b6f6fd-f3ec-4532-8579-179282610aban%40googlegroups.com.

Reply via email to