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

pointers to slice elements in a []byte("string") are != #1569

Closed
thehowl opened this issue Jan 23, 2024 · 0 comments · Fixed by #1601
Closed

pointers to slice elements in a []byte("string") are != #1569

thehowl opened this issue Jan 23, 2024 · 0 comments · Fixed by #1601
Assignees
Labels
🐞 bug Something isn't working 📦 🤖 gnovm Issues or PRs gnovm related

Comments

@thehowl
Copy link
Member

thehowl commented Jan 23, 2024

Before you ask: yes, this is specifically byte slices which are created as a result of string conversion.

package main

func main() {
	{
		b := []byte("ABCDEFGHIJKL")
		a := b
		println(&b[0] == &a[0], b[0], a[0])

		// modifying the underlying array modifies both a[0] and b[0],
		// as it should
		a[0] = 11
		println(a[0], b[0])
	}

	{
		b := []byte{1, 2, 3}
		a := b
		println(&b[0] == &a[0], b[0], a[0])

		// modifying the underlying array modifies both a[0] and b[0],
		// as it should
		a[0] = 11
		println(a[0], b[0])
	}
}

// Output:
// false 65 65
// 11 11
// true 1 1
// 11 11
@thehowl thehowl added 🐞 bug Something isn't working 📦 🤖 gnovm Issues or PRs gnovm related labels Jan 23, 2024
@thehowl thehowl added this to the 🚀 main.gno.land (required) milestone Jan 23, 2024
@thehowl thehowl self-assigned this Jan 23, 2024
@thehowl thehowl removed their assignment Jan 23, 2024
@thehowl thehowl changed the title pointers to slice elements in a byte slice are != pointers to slice elements in a []byte("string") are != Jan 23, 2024
@ltzmaxwell ltzmaxwell self-assigned this Jan 29, 2024
@deelawn deelawn linked a pull request Feb 14, 2024 that will close this issue
petar-dambovaliev pushed a commit that referenced this issue Apr 9, 2024
This is a fix to #1569 . Thanks to @thehowl for identifying this issue
and providing a thorough and insightful analysis.

Here is an further analysis based on #1569 :

```go
package main

func main() {
	{
		b := []byte("ABCDEFGHIJKL")
		a := b
		println(&a[0] == &a[0])
	}
}
```
this comparison would be false too.


The root cause for this is the way pointer values is obtained and
compared, e.g.
```go
package main

func main() {
	c := []byte{'A'}
	a := c
	println(&c[0])
	println(&c[0] == &a[0])
}
```

in this code snippet, the address of the c[0], (&c[0]) is obtained from
this:
```go
    ev := fillValueTV(store, &av.List[ii]) // by reference
```
that is a reference to the element of the underlying list of arrayValue,

in case like this:
```go
package main

func main() {
	{
		b := []byte("ABCDEFGHIJKL")
		a := b
		println(&a[0] == &a[0])
	}
}
```
the address is obtained by
```go
	bv := &TypedValue{ // heap alloc, so need to compare value rather than pointer in isEql(), line 482
		T: DataByteType,
		V: DataByteValue{
			Base:     av,
			Index:    ii,
			ElemType: et,
		},
	}
```
that is a new allocated *TV, which implies the value of it would not be
same within the first and second & operation.
So we should actually compare the concrete value rather than the
pointers for this case.
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
Development

Successfully merging a pull request may close this issue.

3 participants