Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Incorrect lhs evaluation order in multi-assignments #358

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

Open
shibukawa opened this issue Dec 5, 2015 · 6 comments
Open

Incorrect lhs evaluation order in multi-assignments #358

shibukawa opened this issue Dec 5, 2015 · 6 comments

Comments

@shibukawa
Copy link

The following code reproduces the issue I met.

https://gist.github.com/shibukawa/44cb0529c492e0679e9c

I am using one slice technique, deleting pointer member, described at here:
https://github.com/golang/go/wiki/SliceTricks

The result is different from Golang. Gopher.js overwrites the last member that should not be removed with nil.

@theclapp
Copy link

theclapp commented Dec 5, 2015

I found this kind of fascinating so I looked into it.

So this breaks in GopherJS (the assignment itself doesn't break; a later defer [edit: deref] breaks trying to do, essentially, nil.index):

slice, slice[len(slice)-1] = append(slice[:delIndex], slice[delIndex+1:]...), nil

This breaks in Go and GopherJS, in the same way as the above, and is probably what GopherJS is doing:

 slice = append(slice[:delIndex], slice[delIndex+1:]...)
 slice[len(slice)-1] = nil

This works in Go and GopherJS, and is probably what GopherJS should be doing:

t1 := &slice[len(slice)-1]
slice = append(slice[:delIndex], slice[delIndex+1:]...)
*t1 = nil

The Go spec says

The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.

So GopherJS is apparently violating the "First" bit, in this case.

@dmitshur dmitshur added the bug label Dec 7, 2015
@dmitshur
Copy link
Member

dmitshur commented Dec 7, 2015

I can reproduce. This looks like a valid bug. Thanks for the report @shibukawa and for looking into it @theclapp. I think your analysis is correct.

@neelance
Copy link
Member

neelance commented Dec 7, 2015

@shibukawa Thanks for the bug report. Please give me some time to fix it, since the solution is not straightforward. JS has no pointers, they can only be emulated which is slow. I want to avoid this and instead have a more involved solution which is fast for the most cases.

@shibukawa
Copy link
Author

Thank you!

It is not urgent for me because my code already uses working around code to avoid this issue. Enjoy holidays. Gopher.js is awesome.

@dmitshur dmitshur changed the title Deleting slice member code works differently with Golang 1.5 Multiple assignment order of operations bug. Dec 14, 2015
@dmitshur
Copy link
Member

@renfredxh just ran into this too. We worked around it, so it's not urgent, but fixing this will definitely be nice.

@nevkontakte
Copy link
Member

Copying from #1063:

The spec says the following:

The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.

However, gopherjs evaluates lhs expressions at the time of assignment. In situations when one of the assignments modifies a variable referenced by another assignment, the result may be incorrect. For example:

package main

func main() {
        type T struct{ i int }
        var x T
        p := &x
        p, p.i = new(T), 4
        println(p.i, x.i)
}

Go prints 0 4
GopherJS prints 4 0

Related: golang/go#23017.

@nevkontakte nevkontakte added this to the Go spec compliance milestone Oct 27, 2021
@nevkontakte nevkontakte changed the title Multiple assignment order of operations bug. Incorrect lhs evaluation order in multi-assignments Oct 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants