[libcxx-commits] [PATCH] D117332: [libc++] Make sure basic_string::reserve never shrinks in all standard modes
Arthur O'Dwyer via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jan 20 20:06:39 PST 2022
Quuxplusone accepted this revision as: Quuxplusone.
Quuxplusone added inline comments.
================
Comment at: libcxx/docs/ReleaseNotes.rst:111-115
+- Calling ``std::basic_string::reserve()`` used to shrink the string if it could in all Standard modes.
+ Calling ``std::basic_string::reserve(capacity)`` used to shrink the string if it could in C++17 and before,
+ but not in C++20 and later. This behavior was changed so that both these calls never shrink the string
+ consistently in all Standard modes. This is a conforming implementation of the Standard, and this change
+ was done to avoid serious ODR violations when mixing code compiled in different Standard modes.
----------------
Quuxplusone wrote:
> Consider reflowing to fit in Phab's column count. :)
> "so that both these calls never shrink the string consistently in all Standard modes" — so they always shrink it inconsistently? 😛 Suggestion:
> ```
> - C++20 requires that ``std::basic_string::reserve`` never reduce the capacity
> of the string. (For that, use ``shrink_to_fit``.) Prior to this release, libc++'s
> ``std::basic_string::reserve(n)`` could reduce capacity in C++17 and before,
> but not in C++20 and later. This caused ODR violations when mixing code compiled
> under different Standard modes. After this change,
> ``std::basic_string::reserve(n)`` never reduces capacity, even in C++17
> and before.
> Also, after this change, `std::basic_string::reserve()`` is treated as a no-op,
> rather than as a synonym for ``shrink_to_fit()``. [Arthur says: Why?]
> ```
> The rationale is that `reserve()` is supposed to be the same as `reserve(0)` -- actually in C++03 `reserve` is specified as a single overload with a default argument: `reserve(int = 0)`. If I make `reserve()` a synonym for `shrink_to_fit()`, it won't be equivalent to `reserve(0)` anymore.
`reserve()` is explicitly //supposed// to not-be-equivalent to `reserve(0)`, in C++20 and later... but, at the same time, it's also explicitly deprecated. Okay, I buy that. I'd explain it like this:
```
- C++20 requires that ``std::basic_string::reserve(n)`` never reduce the capacity
of the string. (For that, use ``shrink_to_fit``.) Prior to this release, libc++'s
``std::basic_string::reserve`` could reduce capacity in C++17 and before,
but not in C++20 and later. This caused ODR violations when mixing code compiled
under different Standard modes. After this change, libc++'s
``std::basic_string::reserve`` never reduces capacity, even in C++17
and before.
C++20 deprecates the zero-argument overload of ``std::basic_string::reserve()``,
but specifically permits it to reduce capacity. libc++ does not take advantage
of this permission: we treat ``reserve()`` as a synonym for ``reserve(0)``
in all Standard modes.
```
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D117332/new/
https://reviews.llvm.org/D117332
More information about the libcxx-commits
mailing list