This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Default std::vector<bool> default and move constructor


On 26/05/17 23:13 +0200, François Dumont wrote:
On 25/05/2017 18:28, Jonathan Wakely wrote:
On 15/05/17 19:57 +0200, François Dumont wrote:
Hi

Following what I have started on RbTree here is a patch to default implementation of default and move constructors on std::vector<bool>.

As in _Rb_tree_impl the default allocator is not value initialized anymore. We could add a small helper type arround the allocator to do this value initialization per default. Should I do so ?

It's required to be value-initialized, so if your patch changes that
then it's a problem.

Did we decide it's OK to do that for RB-trees? Did we actually discuss
that part of the r243379 changes?

I remember a message pointing this issue but after the commit AFAIR. I thought it was from Tim but I can't find it on the archive.

What is the rational of this requirement ? I started working on a type to do the allocator value initialization if there is no default constructor but it seems quite complicated to do so. It is quite sad that we can't fully benefit from this nice C++11 feature just because of this requirement. If there is any initialization needed it doesn't sound complicated to provide a default constructor.

The standard says that the default constructor is:

 vector() : vector(Allocator()) { }

That value-initializes the allocator. If the allocator type behaves
differently for value-init and default-init (e.g. it has data members
that are left uninitialized by default-init) then the difference
matters. If you change the code so it only does default-init of the
allocator then you will introduce an observable difference.

I don't see any requirement that a DefaultConstructible allocator
cannot leave members uninitialized, so that means the standard
requires default construction of vector<bool> to value-init the
allocator. Not default-init.

Here's an allocator that behaves differently if value-initialized or
default-initialized:

template<typename T>
struct Alloc {
 using value_type = T;
 Alloc() = default;
 template<typename U>
   Alloc(const Alloc<U>& a) : mem(a.mem) { }
 T* allocate(std::size_t n) {
   if (mem)
     throw 1;
   return std::allocator<T>().allocate(n);
 }
 void deallocate(T* p, std::size_t n) {
   std::allocator<T>().deallocate(p, n);
 }

 int mem;
};

template<typename T, typename U>
bool operator==(const Alloc<T>& t, const Alloc<U>& u)
{ return t.mem == u.mem; }

template<typename T, typename U>
bool operator!=(const Alloc<T>& t, const Alloc<U>& u)
{ return !(t == u); }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]