You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
libc++ documents that it has implemented P0966R1[1][2], "string::reserve Should Not Shrink", but as far as I can tell, string::reserve still shrinks the capacity.
P0966R1 allows reserve() and reserve(0) to do different things, so they need to be overloads rather than use a default argument of 0, and the libc++ commit does split the function into two overloaded functions. libc++'s string::reserve(size_type) function still lowers the capacity, though. Its shrink_to_fit() still calls reserve(), which calls reserve(0).
constexpr void reserve(size_type res_arg);
Effects: A directive that informs a basic_string of a planned change in size, so that the storage allocation can be managed accordingly. After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise. Reallocation happens at this point if and only if the current capacity is less than the argument of reserve().
The libc++ commit added a test that looks like it verifies that reserve doesn't shrink, but it doesn't really do that. In string.capacity/reserve.pass.cpp:
We have a string, s with size() == 50 and capacity() >= 100. Calling reserve(5) should leave the capacity() >= 100 as of P0966R1, but libc++ shrinks the string to a little above 50. However, main() passes the string by-value to test(), and the copy constructor makes a new string that's shrunk-to-fit. i.e. AFAICT, the sections in main() that use erase() aren't testing the intended situation.
The text was updated successfully, but these errors were encountered:
Extended Description
libc++ documents that it has implemented P0966R1[1][2], "string::reserve Should Not Shrink", but as far as I can tell, string::reserve still shrinks the capacity.
[1] https://libcxx.llvm.org/cxx2a_status.html
[2] http://wg21.link/P0966R1
The P0966R1 change was implemented in D54992[3] / svn commit 347789[4].
[3] https://reviews.llvm.org/D54992
[4] https://reviews.llvm.org/rL347789
P0966R1 allows reserve() and reserve(0) to do different things, so they need to be overloads rather than use a default argument of 0, and the libc++ commit does split the function into two overloaded functions. libc++'s string::reserve(size_type) function still lowers the capacity, though. Its shrink_to_fit() still calls reserve(), which calls reserve(0).
http://eel.is/c++draft/string.capacity#itemdecl:6 reads:
The libc++ commit added a test that looks like it verifies that reserve doesn't shrink, but it doesn't really do that. In string.capacity/reserve.pass.cpp:
(I think the comment meant to say "reserve never shrinks" rather than "resize never shrinks"?)
This call to test() looks like it would catch the issue:
We have a string,
s
with size() == 50 and capacity() >= 100. Calling reserve(5) should leave the capacity() >= 100 as of P0966R1, but libc++ shrinks the string to a little above 50. However, main() passes the string by-value to test(), and the copy constructor makes a new string that's shrunk-to-fit. i.e. AFAICT, the sections in main() that use erase() aren't testing the intended situation.The text was updated successfully, but these errors were encountered: