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

Values of slice not being copied properly by reference #1796

Closed
leohhhn opened this issue Mar 19, 2024 · 3 comments
Closed

Values of slice not being copied properly by reference #1796

leohhhn opened this issue Mar 19, 2024 · 3 comments
Labels
🐞 bug Something isn't working 📦 🤖 gnovm Issues or PRs gnovm related

Comments

@leohhhn
Copy link
Contributor

leohhhn commented Mar 19, 2024

Description

I believe I found an issue in the GnoVM, while writing the Memeland realm. With the following code:

type Post struct {
	ID            string
	Data          string
	Author        std.Address
	Timestamp     time.Time
	UpvoteTracker *avl.Tree // address > struct{}{}
}

type Memeland struct {
	Posts       []*Post
}

When making a pointer copy of m.Posts, and updating that value, the m.Posts slice does not get updated.

posts := m.Posts // copy pointer to m.Posts slice

for i, post := range posts {
	// deleting a specific element
        if post.ID == id {
		posts = append(posts[:i], posts[i+1:]...)
                // `posts` will be updated, m.Posts will not
		return id
	}
}
@leohhhn leohhhn added 🐞 bug Something isn't working 📦 🤖 gnovm Issues or PRs gnovm related labels Mar 19, 2024
@notJoon
Copy link
Member

notJoon commented Mar 20, 2024

Assuming the behavior in the Gno is identical to that of the Go language for convenience.

In Go, slices are fundamentally reference types. When using posts := m.Posts, both posts and m.Posts point to the same data. But they operate as separate references (i.e., independent slices). This means that while metadata (length or capacity) of the slice is copied, the content of the data array they internally point to is shared.

Therefore, deleting an element from the posts slice does not affect the m.Posts slice because although both slices access the same data array, each slice has different metadata. Due to these characteristics, changes made to posts are not reflected in m.Posts IMHO.

Here's my reproduction code:

  1. change on posts
  2. directly change on m.Posts

@deelawn
Copy link
Contributor

deelawn commented Mar 20, 2024

I think we can close this as intended behavior. @notJoon is mostly correct -- but many cases modifying a single slice element will affect other slices that reference the same underlying array, and this is intended to mirror the go functionality. Slices will continue to use the same underlying array until the array needs to grown / reallocated.

Here is an example: https://play.gno.land/p/zSEYhS76ym3

@leohhhn please close if you agree.

@leohhhn
Copy link
Contributor Author

leohhhn commented Mar 25, 2024

Looking into this in more detail, it is actually intended behavior. Closing this. Thanks @notJoon @deelawn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 bug Something isn't working 📦 🤖 gnovm Issues or PRs gnovm related
Projects
None yet
Development

No branches or pull requests

3 participants