Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

affected/package: types convert: Why do []interface{} and interface{} behave differently when they convert the same variable c? #59863

Closed
abserari opened this issue Apr 27, 2023 · 1 comment

Comments

@abserari
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.20.1 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/abser/.cache/go-build"
GOENV="/home/abser/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/abser/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/abser/go"
GOPRIVATE=""
GOPROXY=""
GOROOT="/usr/local/go"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.1"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/abser/code/demo/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1910517605=/tmp/go-build -gno-record-gcc-switches"

What did you do?

https://go.dev/play/p/rwPqGhlZZ-v

In this application, you can see uint8 type c assigning the values to i, i2, and doing the conversion directly, which means you can see he uint8 type c converted to interface{} which is always a consistent address which is understandable here.

And then the second example

https://go.dev/play/p/OkwzZBDx3F6
This example again uses the type c which uint8 assigns the value to i, In addition, the unsafe package is converted into a pointer p, which is used to modify the value of i. After testing in fmt.Println(c), the value modified by p actually affects C. The output of fmt.Println(c) is 30, but the value of c can be seen through println 20 This is because c is converted into the []interface{} type into fmt.Println and he uint8 is the same memory address when he uint8 does the interface{} conversion

And then the third example
https://go.dev/play/p/Xe9jSkIxLsf
Changing c to uint32 et (not uint8 or uint8 type), you can see that modifying the value of p doesn't affect c, which is for sure because c interprets the address inconsistently incrementing each time through interface{} because golang is a copy of values

Finally, when we add any value to fmt.Println(c), such as fmt.Println(p, c), we find that even the uint32 c variable is changed by p to print 30 in the fourth example
https://go.dev/play/p/eehpicB-SCE

What did you expect to see?

In the fourth case, when converting c and other params to interface{}, The same memory address is not used. And fmt.Println(c) would be 20 output.

What did you see instead?

I'm confused about the rule of []interface{} doing the transformation, why would this appear the same address when converting uint8 type and others type are not.

Why do []interface{} and interface{} behave differently when they convert the same variable c?

Very grateful for possible answers. and paste the test code below:

package main

import (
	"fmt"
	"unsafe"
)

type ef struct {
	_type unsafe.Pointer
	data  unsafe.Pointer
}

func main() {
	var c uint32 = 20
	var i interface{} = c
	p := unsafe.Pointer(&i)
	ptr := (*ef)(p)
	p2 := (*int64)(ptr.data)
	*p2 = 30
	println(c) // output: 20

	fmt.Println(p, c) // output: 0xc000014270 30
}
@seankhliao
Copy link
Member

this isn't an operation we support.

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Apr 27, 2023
@golang golang locked and limited conversation to collaborators Apr 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants