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

Explicitly mention that Vec::reserve is based on len not capacity #39701

Merged
merged 1 commit into from
Feb 11, 2017

Conversation

sgrif
Copy link
Contributor

@sgrif sgrif commented Feb 9, 2017

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 the
current capacity not the current length. It would be helpful if this
were called out explicitly in the docs.
@keeperofdakeys
Copy link
Contributor

While you're here, I wonder if you shouldn't update the truncate and clear documentation, mentioning that they explicitly don't touch capacity. The last time I used them, I had to verify their functionality from the code :/.

@alexcrichton
Copy link
Member

@bors: r+

Thanks @sgrif! We should always be able to follow up with @keeperofdakeys's suggestion in a further PR

@bors
Copy link
Contributor

bors commented Feb 10, 2017

📌 Commit b3937ea has been approved by alexcrichton

@alexcrichton
Copy link
Member

@bors: rollup

@bors
Copy link
Contributor

bors commented Feb 10, 2017

⌛ Testing commit b3937ea with merge c20ce8e...

@bors
Copy link
Contributor

bors commented Feb 10, 2017

💔 Test failed - status-appveyor

@alexcrichton
Copy link
Member

alexcrichton commented Feb 10, 2017 via email

/// 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`.
Copy link
Contributor

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?

Copy link
Member

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:

/// 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.

Copy link
Contributor

@codyps codyps Feb 10, 2017

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.

Copy link
Member

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.

Copy link
Member

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.

Copy link
Contributor

@codyps codyps Feb 10, 2017

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.

Copy link
Contributor Author

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.

Copy link
Member

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

Copy link
Member

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.

Copy link
Member

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.

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Feb 10, 2017
…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
Copy link
Member

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”

Copy link
Member

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".

@frewsxcv
Copy link
Member

@bors r-

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Feb 11, 2017

📌 Commit b3937ea has been approved by alexcrichton

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Feb 11, 2017
…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.
frewsxcv added a commit to frewsxcv/rust that referenced this pull request Feb 11, 2017
…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.
bors added a commit that referenced this pull request Feb 11, 2017
Rollup of 9 pull requests

- Successful merges: #39174, #39660, #39676, #39692, #39701, #39710, #39721, #39724, #39725
- Failed merges:
@bors bors merged commit b3937ea into rust-lang:master Feb 11, 2017
@sgrif sgrif deleted the sg-vec-reserve-docs branch February 11, 2017 10:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants