Whether capacity of strings shrinks depends on whether the strings are shared. I believe this also true for 4.0.1, but I only have the sources of it, didn't compile. To reproduce (note that `s2' is not shared at the time of push): int main() { string s1; s1.reserve (10000); string s2 = s1; s1.push_back ('!'); s2.push_back ('!'); cout << "s1 capacity: " << s1.capacity () << endl; cout << "s2 capacity: " << s2.capacity () << endl; return 0; } Output (here): s1 capacity: 1 s2 capacity: 12259
Why do you think this is a bug.
Because it defeats the effect of reserve() call on `s1'. I'm not saying I know how to avoid it, but I wonder if there is some strict policy behind `std::basic_string' reallocation behavior in GNU STL. Maybe this example shows that the policy is not implemented properly. I think this example shows a perfectly common usage of strings where you reserve space for all the things you are going to stuff in the string and then make a copy of an intermediate results. With current GNU STL behavior, this doesn't work as expected, though, of course, it *will* give the correct result, it is only about optimizations.
When push_back notices that s1 is shared and clones it (via reserve), creates a new string (not shared) of capacity >= original size (according to an exponential grow policy) but unrelated to the original capacity. I don't think it would be wise to always take into account the original capacity, which can be > size for *zillions* of different reasons, depending on the history of the string, and not explicitly requested by the user via a previous reserve. Also notice that a *series* of push_back is typically very fast, because of the exponential reallocation policy and very often there is no real need for a reserve to obtain good performance. Also notice that some artifacts are generally considered unavoidable in a reference counted implementation of string, as our default one (in mainline, we provide also an alternate implementation in ext/vstring.h)
Of course, first copy-constructing s2, then calling s1.reserve also makes sense.
In fact, there isn't much more to say or do...