Topic: Sequence container capacity after calling clear()


Author: Leigh Johnston <leigh@i42.co.uk>
Date: Sat, 23 Mar 2013 16:27:46 CST
Raw View
Hi,

Can we please change the ISO C++ Standard so that explicitly states what
happens to a sequence container's capacity() after calling clear()?

Currently the behaviour is unspecified and I know of at least one
implementation that deallocates on vector<T>::clear().

If the behaviour remains unspecified then it is effectively impossible
to write portable code that uses clear() and you have to hope things
such as v.erase(v.begin(), v.end()) behave more consistently across
different implementations.

/Leigh


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Sat, 23 Mar 2013 22:05:32 -0700 (PDT)
Raw View
Am 23.03.2013 23:27, schrieb Leigh Johnston:
>
>
> Can we please change the ISO C++ Standard so that explicitly states what
> happens to a sequence container's capacity() after calling clear()?
>
> Currently the behaviour is unspecified and I know of at least one
> implementation that deallocates on vector<T>::clear().
>
> If the behaviour remains unspecified then it is effectively impossible
> to write portable code that uses clear() and you have to hope things
> such as v.erase(v.begin(), v.end()) behave more consistently across
> different implementations.


This problem was already cause of a previous library issue:

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#1102

Please provide this link to the vendor of the buggy library you have in mind.

HTH & Greetings from Bremen,

Daniel Kr   gler



--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Jason McKesson <jmckesson@googlemail.com>
Date: Sat, 23 Mar 2013 22:05:54 -0700 (PDT)
Raw View
On Saturday, March 23, 2013 2:30:03 PM UTC-7, Leigh Johnston wrote:
> Hi,
>
>
>
> Can we please change the ISO C++ Standard so that explicitly states what
>
> happens to a sequence container's capacity() after calling clear()?
>
>
>
> Currently the behaviour is unspecified and I know of at least one
>
> implementation that deallocates on vector<T>::clear().
>
>
>
> If the behaviour remains unspecified then it is effectively impossible
>
> to write portable code that uses clear() and you have to hope things
>
> such as v.erase(v.begin(), v.end()) behave more consistently across
>
> different implementations.

I don't see what's non-portable about this.

If you don't care what the capacity is, you use `clear` and let the
implementation decide. It's not non-portable because your code
*doesn't care*. If you *do* care about the capacity, then you either
want the capacity to be zeroed out or you want it to be preserved. And
you already have the tools to do either:

    vec.resize(0); //Destroys contents, but doesn't change the capacity.
    vec = vector<T>{}; //Destroys contents and reduces the capacity.

Both of these are reasonable behaviors, so the user should be able to
do either if they want a specific result.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Juha Nieminen <nospam@thanks.invalid>
Date: Sun, 24 Mar 2013 23:36:42 -0700 (PDT)
Raw View
In comp.lang.c++ Leigh Johnston <leigh@i42.co.uk> wrote:
> Currently the behaviour is unspecified and I know of at least one
> implementation that deallocates on vector<T>::clear().

One would think that such an implementation would get so many complaints
that they would fix that.

I don't think it's extremely rare for people to use std::vector as a
buffer to do some data manipulation. If said code is called very
frequently, then allocating a new array every single time would have
a really big impact on performance, so it's better to reuse the one
and same std::vector instance each time (by either making it 'static'
if it's inside the function, a member function of the class, if this
is a class, or a compilation-unit-local object.)

If this is so, then usually you want to clear the vector before
doing anything with it, so that it doesn't contain anything from the
previous run (assuming that you don't know in advance how many elements
there will be in the vector.)

If the vector implementation works as usual, this is a fast operation
because a 'clear()' will simply destroy the objects and set the size
to zero, but not actually free the memory. Thus it will work as a
static memory buffer.

However, if 'clear()' frees the memory, that means that there will be
a deallocation and an allocation every single time that the function is
called, having a big impact in performance. The only way to make sure
that this doesn't happen is to bypass std::vector and make your own
class which manages a dynamic array. The value of std::vector as a
useful tool has thus been diminished.

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: Mathias Gaunard <loufoque@googlemail.com>
Date: Mon, 25 Mar 2013 10:49:44 CST
Raw View
On Mar 23, 10:30 pm, Leigh Johnston <le...@i42.co.uk> wrote:
> Hi,
>
> Can we please change the ISO C++ Standard so that explicitly states what
> happens to a sequence container's capacity() after calling clear()?
>
> Currently the behaviour is unspecified and I know of at least one
> implementation that deallocates on vector<T>::clear().
>
> If the behaviour remains unspecified then it is effectively impossible
> to write portable code that uses clear() and you have to hope things
> such as v.erase(v.begin(), v.end()) behave more consistently across
> different implementations.

Use shrink_to_fit if you want to reduce capacity to 0 after a clear.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Leigh Johnston <leigh@i42.co.uk>
Date: Tue, 26 Mar 2013 08:55:38 CST
Raw View
On 25/03/2013 16:49, Mathias Gaunard wrote:
>
> On Mar 23, 10:30 pm, Leigh Johnston <le...@i42.co.uk> wrote:
>> Hi,
>>
>> Can we please change the ISO C++ Standard so that explicitly states what
>> happens to a sequence container's capacity() after calling clear()?
>>
>> Currently the behaviour is unspecified and I know of at least one
>> implementation that deallocates on vector<T>::clear().
>>
>> If the behaviour remains unspecified then it is effectively impossible
>> to write portable code that uses clear() and you have to hope things
>> such as v.erase(v.begin(), v.end()) behave more consistently across
>> different implementations.
>
> Use shrink_to_fit if you want to reduce capacity to 0 after a clear.

You didn't grok my post properly.  I want the opposite: I want the
capacity to be unchanged after calling clear().

/Leigh


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@googlemail.com>
Date: Wed, 27 Mar 2013 13:28:17 CST
Raw View
On Sunday, 24 March 2013 05:05:32 UTC, Daniel Kr   gler  wrote:
> Am 23.03.2013 23:27, schrieb Leigh Johnston:
> > Can we please change the ISO C++ Standard so that explicitly states what
> > happens to a sequence container's capacity() after calling clear()?

> > Currently the behaviour is unspecified and I know of at least one
> > implementation that deallocates on vector<T>::clear().

> > If the behaviour remains unspecified then it is effectively impossible
> > to write portable code that uses clear() and you have to hope things
> > such as v.erase(v.begin(), v.end()) behave more consistently across
> > different implementations.

> This problem was already cause of a previous library issue:

> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#1102

> Please provide this link to the vendor of the buggy library you have in mind.

I, for one, would like to see the issue reopened.  I understand
the logic behind the current resolution, but I think it is less
than clear.  Particularly because:

 1. The guarantees with regards to the validity of iterators and
        the absense of reallocation are given with regards to
        a previous call to reserve.  In other words, clear() cannot
        reduce the capacity IF the capacity was the result of a call
        to reserve.  Now, we all know that no implementation is
        going to make clear() behave differently depending on
        whether reserve() was called or not, but technically, it
        might be legal.

 2. C++11 has changed the definition of clear().  It used to be
        defined in terms of erase(); erase() is documented to only
        invalidate iterators at or after the elements which are
        erased.  Logically, I suppose that one could argue that if
        all of the elements are erased, it could invalidate all
        iterators, but again, one would not expect such special
        casing, and it would seem to violate at least the intent of
        the standard.  Now that clear() is no longer defined in
        terms of erase(), however, such indirect argumentation is
        seriously weakened.

I'd really like to see this specified a bit clearer, even if
there seems to be a consensus in the committee as to what is
meant.  (I noticed that C++11 also reduces guarantees elsewhere,
and has rendered an expression like s[i] == s[j] invalid if s is
a non-const std::string.  Luckily, all of the implementors seem
to know what is wanted, and implement something reasonable, but
still, it would be nice to have it guaranteed.)

--
James


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]