On 09/10/2016 17:14, Jonathan Wakely wrote: > On 08/10/16 22:55 +0200, François Dumont wrote: >> On 06/10/2016 23:34, Jonathan Wakely wrote: >>> On 06/10/16 22:17 +0200, François Dumont wrote: >>>> Another approach is to rely on existing compiler ability to compute >>>> conditional noexcept when defaulting implementations. This is what >>>> I have done in this patch. >>>> >>>> The new default constructor on _Rb_tree_node_base is not a problem >>>> as it is not used to build _Rb_tree_node. >>> >>> Why not? >> >> _Rb_tree_node_base is used in 2 context. As member of _Rb_tree_impl >> in which case we need the new default constructor. And also as base >> class of _Rb_tree_node which is never constructed. Nodes are being >> allocated and then associated value is being constructed through the >> allocator, the node default constructor itself is never invoked. > > In C++03 mode that is true, but it's only valid because the type is > trivially-constructible. If the type requires "non-vacuous > initialization" then it's not valid to allocate memory for it and > start using it without invoking a constructor. Good to know. > If you add a > non-trivial constructor then we can't do that any more. > > In C++11 and later, see line 550 in > > ::new(__node) _Rb_tree_node<_Val>; > > This default-constructs a tree node. Currently there is no > user-provided default constructor, so default-construction does no > initialization. Adding your constructor would mean it is used for > every node. I missed this call, indeed. I should have deleted default constructor and run compilation to be sure. > >> If you think it is cleaner to create an intermediate type that >> will take care of this initialization through its default constructor >> I can do that. >> >>> >>>> I'll try to do the same for copy constructor/assignment and move >>>> constructor/assignment. >>> >>> We need to make sure we don't change whether any of those operations >>> are trivial (which shouldn't be a problem for copy/move, because they >>> are definitely very non-trivial and will stay that way!) >>> >>> Does this change the default constructors from non-trivial to trivial? >> It would be a major compiler bug if making a constructor default was >> making it trivial. > > I must be misunderstanding you, because this is not a bug: No, my fault, I was misunderstanding you. Now that I know about validity of using a "non-constructed" type only if trivial, it is much clearer. So here is the fixed patch with your proposed intermediate type containing the necessary default constructor. Being tested, ok to commit if successful ? François