Default std::vector<bool> default and move constructor
François Dumont
frs.dumont@gmail.com
Thu Jun 1 20:49:00 GMT 2017
On 01/06/2017 15:34, Jonathan Wakely wrote:
> On 31/05/17 22:28 +0200, François Dumont wrote:
>> Unless I made a mistake it revealed that restoring explicit call to
>> _Bit_alloc_type() in default constructor was not enough. G++ doesn't
>> transform it into a value-init if needed. I don't know if it is a
>> compiler bug but I had to do just like presented in the Standard to
>> achieve the expected behavior.
>
> That really shouldn't be necessary (see blow).
>
>> This value-init is specific to post-C++11 right ? Maybe I could
>> remove the useless explicit call to _Bit_alloc_type() in pre-C++11
>> mode ?
>
> No, because C++03 also requires the allocator to be value-initialized.
Ok so I'll try to make the test C++03 compatible.
>
>> Now I wonder if I really introduced a regression in rb_tree...
>
> Yes, I think you did. Could you try to verify that using the new
> default_init_allocator?
I did and for the moment I experiment the same result with rb_tree than
the one I am having with std::vector<bool>, strange.
I plan to add this test to all containers.
>
>
>> + struct _Bvector_impl
>> + : public _Bit_alloc_type, public _Bvector_impl_data
>> + {
>> + public:
>> +#if __cplusplus >= 201103L
>> + _Bvector_impl()
>> + noexcept( noexcept(_Bit_alloc_type())
>> + && noexcept(_Bvector_impl(declval<const
>> _Bit_alloc_type&>())) )
>
> This second condition is not needed, because that constructor should
> be noexcept (see below).
>
>> + : _Bvector_impl(_Bit_alloc_type())
>
> This should not be necessary...
>
>> + { }
>> +#else
>> _Bvector_impl()
>> - : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage()
>> + : _Bit_alloc_type()
>> { }
>> +#endif
>
> I would expect the constructor to look like this:
>
> _Bvector_impl()
> _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type()) )
> : _Bit_alloc_type()
> { }
>
> What happens when you do that?
This is what I tried first and test was then failing. It surprised me too.
>
>
>> _Bvector_impl(const _Bit_alloc_type& __a)
>> - : _Bit_alloc_type(__a), _M_start(), _M_finish(),
>> _M_end_of_storage()
>> + _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type(__a)) )
>
> Copying the allocator is not allowed to throw. You can use simply
> _GLIBCXX_NOEXCEPT here.
>
>
>> +void test01()
>> +{
>> + typedef default_init_allocator<T> alloc_type;
>> + typedef std::vector<T, alloc_type> test_type;
>> +
>> + test_type v1;
>> + v1.push_back(T());
>> +
>> + VERIFY( !v1.empty() );
>> + VERIFY( !v1.get_allocator().state );
>
> This is unlikely to ever fail, because the stack is probably full of
> zeros anyway. Did you confirm whether the test fails without your
> fixes to value-initialize the allocator?
Yes, the test is failing as soon as I use the default constructor just
calling the allocator default constructor in its initialization list or
when I default this implementation.
>
> One possible way to make it fail would be to construct the
> vector<bool> using placement new, into a buffer filled with non-zero
> values. (Valgrind or a sanitizer should also tell us, but we can't
> rely on them in the testsuite).
>
This is what I have implemented in this new proposal also considering
your other remarks. For the moment if the test fail there is a memory
leak but I prefer to keep implementation simple.
I also start runing the test on the normal std::vector implementation
and I never managed to make the test fail. Even when I default all
default constructor implementations !
I started rebuilding everything.
François
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bvector.patch
Type: text/x-patch
Size: 13256 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20170601/7bdf9f62/attachment.bin>
More information about the Libstdc++
mailing list