-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Explicitly mention that Vec::reserve
is based on len not capacity
#39701
Conversation
I spent a good chunk of time tracking down a buffer overrun bug that resulted from me mistakenly thinking that `reserve` was based on the current capacity not the current length. It would be helpful if this were called out explicitly in the docs.
While you're here, I wonder if you shouldn't update the |
@bors: r+ Thanks @sgrif! We should always be able to follow up with @keeperofdakeys's suggestion in a further PR |
📌 Commit b3937ea has been approved by |
@bors: rollup |
⌛ Testing commit b3937ea with merge c20ce8e... |
💔 Test failed - status-appveyor |
@bors: retry
* github network failure
…On Fri, Feb 10, 2017 at 1:51 AM, bors ***@***.***> wrote:
💔 Test failed - status-appveyor
<https://ci.appveyor.com/project/rust-lang/rust/build/1.0.1886>
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#39701 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAD95J0PIGai1Dyu6ZUlrrTLNUev6ENUks5rbDMJgaJpZM4L8h-Q>
.
|
/// be inserted in the given `Vec<T>`. Does nothing if the capacity is already | ||
/// sufficient. | ||
/// be inserted in the given `Vec<T>`. After calling `reserve_exact`, | ||
/// capacity will be greater than or equal to `self.len() + additional`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be "equal to" rather than "greater than or equal to" given that this "reserves the minimum capacity for [an exact number of additional elements]"?
Or is there a reason to leave the bound open?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For what it's worth, here's a relevant comment in the underlying implementation:
Lines 275 to 280 in b3937ea
/// Ensures that the buffer contains at least enough space to hold | |
/// `used_cap + needed_extra_cap` elements. If it doesn't already, | |
/// will reallocate the minimum possible amount of memory necessary. | |
/// Generally this will be exactly the amount of memory necessary, | |
/// but in principle the allocator is free to give back more than | |
/// we asked for. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, there may be more backing memory. But the Vec::capacity()
(which is what I'm presuming capacity
in the comment refers to here) won't know about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're right. Don't want to mislead people with "greater than or equal to" since it doesn't seem accurate in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assertion in example below has >=
. The implementation calculates the new capacity and just sets it to self.cap (so ==
). The point of the method is to have it be ==
IIRC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sgrif I had presumed that precisely minimal
in that context implied capacity can not be relied upon to be precisely minimal in describing the backing allocation size
, but you're correct that it isn't entirely clear. Is there a desire to allow capacity
to (at some point) more accurately expand to the size of the backing memory returned from the allocator? Could allow eliding calling into the allocator in some cases.
@alexcrichton I had taken the Does nothing if the capacity is already sufficient.
line which immediately follows to create an exception to that. The added sentence could be reworded to make that exception explicit, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to change if y'all think it's necessary. I went with the most conservative statement (and the one that matches the code example). I think if this statement changes, the assertion in the example should change to use ==
as well, however.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sgrif perhaps:
Does nothing if the capacity is already sufficient, or otherwise ensures the capacity is equal to
self.len() + additional
upon returning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
otherwise ensures the capacity is equal to self.len() + additional upon returning
I'm pretty sure we don't guarantee that at the moment. Do we want to start guaranteeing that now? Other collections have a reserve_exact
method which acts the same so any changes should be made to all of them, not just Vec
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, in that case let's just merge as-is.
…ichton Explicitly mention that `Vec::reserve` is based on len not capacity I spent a good chunk of time tracking down a buffer overrun bug that resulted from me mistakenly thinking that `reserve` was based on the current capacity not the current length. It would be helpful if this were called out explicitly in the docs.
@@ -437,7 +437,9 @@ impl<T> Vec<T> { | |||
|
|||
/// Reserves capacity for at least `additional` more elements to be inserted | |||
/// in the given `Vec<T>`. The collection may reserve more space to avoid | |||
/// frequent reallocations. | |||
/// frequent reallocations. After calling `reserve`, capacity will be | |||
/// greater than or equal to `self.len() + additional`. Does nothing if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
“not less than” is a better way to phrase “greater than or equal to”
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally prefer "greater than or equal to".
@bors r- |
@bors: r+ |
📌 Commit b3937ea has been approved by |
…ichton Explicitly mention that `Vec::reserve` is based on len not capacity I spent a good chunk of time tracking down a buffer overrun bug that resulted from me mistakenly thinking that `reserve` was based on the current capacity not the current length. It would be helpful if this were called out explicitly in the docs.
…ichton Explicitly mention that `Vec::reserve` is based on len not capacity I spent a good chunk of time tracking down a buffer overrun bug that resulted from me mistakenly thinking that `reserve` was based on the current capacity not the current length. It would be helpful if this were called out explicitly in the docs.
I spent a good chunk of time tracking down a buffer overrun bug that
resulted from me mistakenly thinking that
reserve
was based on thecurrent capacity not the current length. It would be helpful if this
were called out explicitly in the docs.