Skip to content

reflect: Zero() changes behavior in Go1.16rc1 #43986

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

Closed
koron opened this issue Jan 29, 2021 · 8 comments
Closed

reflect: Zero() changes behavior in Go1.16rc1 #43986

koron opened this issue Jan 29, 2021 · 8 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@koron
Copy link

koron commented Jan 29, 2021

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

$ go version
go version go1.16rc1 windows/amd64

Does this issue reproduce with the latest release?

no. it reprocude with latest release candidate

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

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\koron\AppData\Local\go-build
set GOENV=C:\Users\koron\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\koron\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\koron\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Local\Go\current
set GOSUMDB=sum.golang.org
set GOTMPDIR=C:\Users\koron\go\tmp
set GOTOOLDIR=C:\Local\Go\current\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.16rc1
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\koron\go\tmp\go-build183394138=/tmp/go-build -gno-record-gcc-switches

What did you do?

Run this program with Go 1.16rc1 and 1.15.7

package main

import "reflect"

func main() {
	s := ""
	go116 := reflect.DeepEqual(reflect.Zero(reflect.TypeOf(s)), reflect.ValueOf(s))
	if go116 {
		println("I am Go 1.16 gopher!")
	} else {
		println("I am Go 1.15 or below gopher!")
	}
}

You can get it from https://play.golang.org/p/0tzp7aZhnQ8

What did you expect to see?

reflect.DeepEqual(reflect.Zero(reflect.TypeOf(s)), reflect.ValueOf(s)) returns false for both Go 1.16rc1 and Go 1.15.7

What did you see instead?

Go 1.15.7 returns false, but Go 1.16rc1 returns true

@koron
Copy link
Author

koron commented Jan 29, 2021

possible related change: 8925290

@ALTree ALTree changed the title reflect functions change it behavior at Go1.16rc1 reflect: change in behavior in Go1.16rc1 Jan 29, 2021
@ALTree ALTree added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 29, 2021
@ALTree ALTree added this to the Go1.16 milestone Jan 29, 2021
@ALTree
Copy link
Member

ALTree commented Jan 29, 2021

cc @randall77

@koron koron changed the title reflect: change in behavior in Go1.16rc1 reflect: Zero() changes behavior in Go1.16rc1 Jan 29, 2021
@koron
Copy link
Author

koron commented Jan 29, 2021

I'm thinking it is bad idea comparing two reflect.Value by reflect.DeepEqual.
It was came from https://github.com/go-openapi/validate/blob/bfaa1f86114fc35873e768bea7490439cbc5ee1c/type.go#L140

@seankhliao
Copy link
Member

given that this is in the docs:

To compare two Values, compare the results of the Interface method. Using == on two Values does not compare the underlying values they represent.

I'm thinking this is not a supported operation

@zigo101
Copy link

zigo101 commented Jan 29, 2021

As others mentioned, do

    reflect.DeepEqual(reflect.Zero(reflect.TypeOf(s)).Interface(), s)

instead.

reflect.Value is a struct with some unexported fields. The result of comparing its values depends on the implementations.

@randall77
Copy link
Contributor

I concur, this does not look like a bug. reflect.DeepEqual used on reflect.Values directly almost certainly isn't what you want.
I understand the mistake, though. At first glance it looks like it should work. Maybe a vet check would be worthwhile here?

Anyway, closing. Please reopen if you think this analysis is wrong.

@ianlancetaylor
Copy link
Contributor

See go-openapi/validate#137.

@koron
Copy link
Author

koron commented Jan 30, 2021

Thank you all. I'm satisfied with the conclusion. 👍

@golang golang locked and limited conversation to collaborators Jan 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

7 participants