Skip to content

reflect.Value.Elem is unaddressable for interfaces #17117

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
dmage opened this issue Sep 15, 2016 · 1 comment
Closed

reflect.Value.Elem is unaddressable for interfaces #17117

dmage opened this issue Sep 15, 2016 · 1 comment

Comments

@dmage
Copy link
Contributor

dmage commented Sep 15, 2016

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

tip, go version devel +27eebba

What did you do?

I tried to change the value inside interface{} variable.

i := interface{}("hello")
v := reflect.ValueOf(&i).Elem()
v.Elem().SetString("world")
fmt.Println(i)

https://play.golang.org/p/U8WaCBA4o4

What did you expect to see?

"world" stored in i.

What did you see instead?

Runtime error.

Proposed change

diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
index 780799c..4bb408b 100644
--- a/src/reflect/all_test.go
+++ b/src/reflect/all_test.go
@@ -5752,3 +5752,10 @@ func BenchmarkNew(b *testing.B) {
        New(v)
    }
 }
+
+func TestInterfaceElemSet(t *testing.T) {
+   i := interface{}("hello")
+   v := ValueOf(&i).Elem()
+   v.Elem().SetString("world")
+   assert(t, i.(string), "world")
+}
diff --git a/src/reflect/value.go b/src/reflect/value.go
index e6b846e..0340d25 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -714,6 +714,9 @@ func (v Value) Elem() Value {
        x := unpackEface(eface)
        if x.flag != 0 {
            x.flag |= v.flag & flagRO
+           if x.flag&flagIndir != 0 {
+               x.flag |= flagAddr
+           }
        }
        return x
    case Ptr:
@ianlancetaylor
Copy link
Contributor

That does not correspond to an operation permitted by the language. In the language, a value stored in an interface variable is not addressable. The interface variable is addressable, but not the value contained within. It's also inconsistent: your code permits changing the value if it is something like a string, but not if it is something like a pointer. We're not going to make this change.

@golang golang locked and limited conversation to collaborators Sep 15, 2017
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