Navigation Menu

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

spec: unclear definition of the capacity of a slice #48036

Open
rillig opened this issue Aug 28, 2021 · 3 comments
Open

spec: unclear definition of the capacity of a slice #48036

rillig opened this issue Aug 28, 2021 · 3 comments
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@rillig
Copy link
Contributor

rillig commented Aug 28, 2021

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

https://golang.org/ref/spec says: Version of Jul 26, 2021

What did you do?

After a few years of Go experience, I decided to read the spec again.
When I got to the section about slices, I stumbled upon these sentences:

The array underlying a slice may extend past the end of the slice.
The capacity is a measure of that extent: it is the sum of the length of the slice and the length of the array beyond the slice.

The second sentence seemed wrong to me, so I tried it using go1.16:

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

arr := [5]int{1, 2, 3, 4, 5}
slice := arr[1:2:3]

In the above code, the slice starts at &arr[1], it has length 1 and capacity 2.
The "length of the array beyond the slice" probably refers to "beyond len(slice)". If so, I assume it to be 3.
The sum of these is 1 + 3 == 4, but the capacity of the underlying array is 5.
The spec says the capacity should be 4, but in reality it is 2.

Is the spec wrong in this regard, or did I just interpret it wrong?
In the first sentence, I interpreted that the word "beyond" means "past the end", ignoring the portion of the underlying array that is before the beginning of the slice.

@randall77
Copy link
Contributor

It used to be that the 3-arg slice operator didn't exist, so the spec as written was correct. With the 3-arg slice, it isn't technically true any more; as you showed you can construct smaller slices.
Not sure if it would be worth updating the spec, though. It isn't a formal spec. The concept being described is still correct.

@seankhliao seankhliao changed the title ref/spec: unclear definition of the capacity of a slice spec: unclear definition of the capacity of a slice Aug 29, 2021
@cherrymui
Copy link
Member

https://golang.org/ref/spec#Slice_expressions describes

a[low : high : max] constructs a slice of the same type, and with the same length and elements as the simple slice expression a[low : high]. Additionally, it controls the resulting slice's capacity by setting it to max - low.

So the capacity of a[1:2:3] is 3-1=2.

I think "the sum of the length of the slice and the length of the array beyond the slice" is still correct. You can think the slice expression down-sizes the underlying array.

@cherrymui cherrymui added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Aug 30, 2021
@cherrymui cherrymui added this to the Unplanned milestone Aug 30, 2021
@rillig
Copy link
Contributor Author

rillig commented Aug 30, 2021

@cherrymui I disagree.

The actual situation, as determined experimentally using go1.17, is:

arr[0]   before the slice
arr[1]   slice[0]
arr[2]   slice[0:2:2][1] (beyond len(slice) but still ok since 1 < cap(slice))
arr[3]   after the slice
arr[4]   after the slice

If you interpret "beyond" as meaning the same as "past len(slice)", cap(slice) would include indices 1, 2, 3 and 4, which would result in cap(slice) == 4, but it is actually 2.

If you interpret "beyond" as meaning "outside slice[0:len(slice)], on both sides", cap(slice) would include indices 0, 1, 2, 3 and 4, which would result in cap(slice) == 5, but it is actually 2.

In both cases, the spec does not provide a recipe for calculating the actual cap(slice), that's why I asked for clarification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

3 participants